<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<title>Spatial Model</title>
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
		<meta name="viewport" content="width=device-width initial-scale=1">
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
		<meta http-equiv="Content-Language" content="en-gb">

<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
function togglePopup(material_id) {
  var popup = document.getElementById(material_id);
  popup.classList.toggle("show");
}
</script>

<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
		
	</head>
	<body class="commentary-font">
		<nav role="navigation">
		<h1><a href="../index.html"><img src="../docs-assets/Inform.png" height=72> </a></h1>
<ul><li><a href="../index.html">home</a></li>
</ul><h2>Compiler</h2><ul>
<li><a href="../structure.html">structure</a></li>
<li><a href="../inbuildn.html">inbuild</a></li>
<li><a href="../inform7n.html">inform7</a></li>
<li><a href="../intern.html">inter</a></li>
<li><a href="../services.html">services</a></li>
<li><a href="../secrets.html">secrets</a></li>
</ul><h2>Other Tools</h2><ul>
<li><a href="../inblorbn.html">inblorb</a></li>
<li><a href="../inform6.html">inform6</a></li>
<li><a href="../inpolicyn.html">inpolicy</a></li>
</ul><h2>Resources</h2><ul>
<li><a href="../extensions.html">extensions</a></li>
<li><a href="../kits.html">kits</a></li>
</ul><h2>Repository</h2><ul>
<li><a href="https://github.com/ganelson/inform"><img src="../docs-assets/github.png" height=0> github</a></li>
</ul><h2>Related Projects</h2><ul>
<li><a href="https://github.com/ganelson/inweb"><img src="../docs-assets/github.png" height=0> inweb</a></li>
<li><a href="https://github.com/ganelson/intest"><img src="../docs-assets/github.png" height=0> intest</a></li>
</ul>
		</nav>
		<main role="main">
		<!-- Weave of 'Spatial Model' generated by inweb -->
<div class="breadcrumbs">
    <ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../inform7n.html">Inform7</a></li><li><a href="index.html">if</a></li><li><a href="index.html#3">Chapter 3: Space and Time</a></li><li><b>Spatial Model</b></li></ul></div>
<p class="purpose">A feature which constructs the fundamental spatial model used by IF, to represent containment, support, carrying, wearing, and incorporation.</p>

<ul class="toc"><li><a href="3-sm.html#SP1">&#167;1. Introduction</a></li><li><a href="3-sm.html#SP2">&#167;2. Kinds of interest</a></li><li><a href="3-sm.html#SP12">&#167;12. Properties of interest</a></li><li><a href="3-sm.html#SP15">&#167;15. Spatial data on instances</a></li><li><a href="3-sm.html#SP18">&#167;18. Composite noun-quantifiers</a></li><li><a href="3-sm.html#SP20">&#167;20. Nowhere</a></li><li><a href="3-sm.html#SP23">&#167;23. Here</a></li><li><a href="3-sm.html#SP26">&#167;26. Completing the world model</a></li><li><a href="3-sm.html#SP33">&#167;33. Completing the model, stages III and IV</a></li></ul><hr class="tocbar">

<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. Introduction.</b>The "spatial model" is the aspect of the IF model world which represents
containment, support, carrying, wearing, and incorporation; say, a button
which is part of a shirt which is in a tumble-drier which is in a room
called the Laundry, where there's also a man carrying a box of washing
powder and wearing a dressing gown. That's quite a lot of concepts, but
note that it doesn't include the geographical model of directions, the map,
regions, and so on.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Spatial::start</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">Spatial::start</span></span>:<br/>IF Module - <a href="1-im.html#SP5">&#167;5</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><a href="3-si.html#SP2" class="function-link"><span class="function-syntax">SpatialInferences::create</span></a><span class="plain-syntax">();</span>

<span class="plain-syntax">#</span><span class="identifier-syntax">pragma</span><span class="plain-syntax"> </span><span class="identifier-syntax">clang</span><span class="plain-syntax"> </span><span class="identifier-syntax">diagnostic</span><span class="plain-syntax"> </span><span class="identifier-syntax">push</span>
<span class="plain-syntax">#</span><span class="identifier-syntax">pragma</span><span class="plain-syntax"> </span><span class="identifier-syntax">clang</span><span class="plain-syntax"> </span><span class="identifier-syntax">diagnostic</span><span class="plain-syntax"> </span><span class="identifier-syntax">ignored</span><span class="plain-syntax"> </span><span class="string-syntax">"-Wincompatible-function-pointer-types-strict"</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">PluginCalls::plug</span><span class="plain-syntax">(</span><span class="identifier-syntax">CREATE_INFERENCE_SUBJECTS_PLUG</span><span class="plain-syntax">, </span><a href="3-sm.html#SP10" class="function-link"><span class="function-syntax">Spatial::create_inference_subjects</span></a><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">PluginCalls::plug</span><span class="plain-syntax">(</span><span class="identifier-syntax">NEW_BASE_KIND_NOTIFY_PLUG</span><span class="plain-syntax">, </span><a href="3-sm.html#SP4" class="function-link"><span class="function-syntax">Spatial::new_base_kind_notify</span></a><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">PluginCalls::plug</span><span class="plain-syntax">(</span><span class="identifier-syntax">ACT_ON_SPECIAL_NPS_PLUG</span><span class="plain-syntax">, </span><a href="3-sm.html#SP21" class="function-link"><span class="function-syntax">Spatial::act_on_special_NPs</span></a><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">PluginCalls::plug</span><span class="plain-syntax">(</span><span class="identifier-syntax">COMPLETE_MODEL_PLUG</span><span class="plain-syntax">, </span><a href="3-sm.html#SP26" class="function-link"><span class="function-syntax">Spatial::IF_complete_model</span></a><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">PluginCalls::plug</span><span class="plain-syntax">(</span><span class="identifier-syntax">DEFAULT_APPEARANCE_PLUG</span><span class="plain-syntax">, </span><a href="3-sm.html#SP17" class="function-link"><span class="function-syntax">Spatial::default_appearance</span></a><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">PluginCalls::plug</span><span class="plain-syntax">(</span><span class="identifier-syntax">NAME_TO_EARLY_INFS_PLUG</span><span class="plain-syntax">, </span><a href="3-sm.html#SP11" class="function-link"><span class="function-syntax">Spatial::name_to_early_infs</span></a><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">PluginCalls::plug</span><span class="plain-syntax">(</span><span class="identifier-syntax">NEW_SUBJECT_NOTIFY_PLUG</span><span class="plain-syntax">, </span><a href="3-sm.html#SP16" class="function-link"><span class="function-syntax">Spatial::new_subject_notify</span></a><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">PluginCalls::plug</span><span class="plain-syntax">(</span><span class="identifier-syntax">NEW_PROPERTY_NOTIFY_PLUG</span><span class="plain-syntax">, </span><a href="3-sm.html#SP14" class="function-link"><span class="function-syntax">Spatial::new_property_notify</span></a><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">PluginCalls::plug</span><span class="plain-syntax">(</span><span class="identifier-syntax">PARSE_COMPOSITE_NQS_PLUG</span><span class="plain-syntax">, </span><a href="3-sm.html#SP19" class="function-link"><span class="function-syntax">Spatial::parse_composite_NQs</span></a><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">PluginCalls::plug</span><span class="plain-syntax">(</span><span class="identifier-syntax">SET_KIND_NOTIFY_PLUG</span><span class="plain-syntax">, </span><a href="3-sm.html#SP5" class="function-link"><span class="function-syntax">Spatial::set_kind_notify</span></a><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">PluginCalls::plug</span><span class="plain-syntax">(</span><span class="identifier-syntax">SET_SUBKIND_NOTIFY_PLUG</span><span class="plain-syntax">, </span><a href="3-sm.html#SP6" class="function-link"><span class="function-syntax">Spatial::set_subkind_notify</span></a><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">PluginCalls::plug</span><span class="plain-syntax">(</span><span class="identifier-syntax">INTERVENE_IN_ASSERTION_PLUG</span><span class="plain-syntax">, </span><a href="3-sm.html#SP22" class="function-link"><span class="function-syntax">Spatial::intervene_in_assertion</span></a><span class="plain-syntax">);</span>
<span class="plain-syntax">#</span><span class="identifier-syntax">pragma</span><span class="plain-syntax"> </span><span class="identifier-syntax">clang</span><span class="plain-syntax"> </span><span class="identifier-syntax">diagnostic</span><span class="plain-syntax"> </span><span class="identifier-syntax">pop</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. Kinds of interest.</b>These are kind names to do with spatial layout which Inform provides special
support for; it recognises the English name when defined by the Standard
Rules. (So there is no need to translate this to other languages.)
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="function-syntax">&lt;notable-spatial-kinds&gt;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">room</span><span class="plain-syntax"> |</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">thing</span><span class="plain-syntax"> |</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">container</span><span class="plain-syntax"> |</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">supporter</span><span class="plain-syntax"> |</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">person</span><span class="plain-syntax"> |</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">player</span><span class="character-syntax">'s holdall</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. </b></p>

<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K_room</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K_thing</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K_container</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K_supporter</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K_person</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K_players_holdall</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
</pre>
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. </b></p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Spatial::new_base_kind_notify</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">Spatial::new_base_kind_notify</span></span>:<br/><a href="3-sm.html#SP1">&#167;1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">new_base</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">name</span><span class="plain-syntax">, </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;notable-spatial-kinds&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;&lt;r&gt;&gt;</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">: </span><span class="identifier-syntax">K_room</span><span class="plain-syntax"> = </span><span class="identifier-syntax">new_base</span><span class="plain-syntax">; </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax">: </span><span class="identifier-syntax">K_thing</span><span class="plain-syntax"> = </span><span class="identifier-syntax">new_base</span><span class="plain-syntax">; </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span><span class="plain-syntax">: </span><span class="identifier-syntax">K_container</span><span class="plain-syntax"> = </span><span class="identifier-syntax">new_base</span><span class="plain-syntax">; </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">3</span><span class="plain-syntax">: </span><span class="identifier-syntax">K_supporter</span><span class="plain-syntax"> = </span><span class="identifier-syntax">new_base</span><span class="plain-syntax">; </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">4</span><span class="plain-syntax">: </span><span class="identifier-syntax">K_person</span><span class="plain-syntax"> = </span><span class="identifier-syntax">new_base</span><span class="plain-syntax">; </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">5</span><span class="plain-syntax">: </span><span class="identifier-syntax">K_players_holdall</span><span class="plain-syntax"> = </span><span class="identifier-syntax">new_base</span><span class="plain-syntax">; </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>&#167;5. </b>When the rest of Inform makes something a room, for instance in response to
an explicit sentence like "The Hall of Mirrors is a room.", we take notice;
if it turns out to be news, we infer <span class="extract"><span class="extract-syntax">is_room_inf</span></span> with certainty.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Spatial::set_kind_notify</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">Spatial::set_kind_notify</span></span>:<br/><a href="3-sm.html#SP1">&#167;1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">k</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kw</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Instances::to_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((!(</span><span class="identifier-syntax">Kinds::Behaviour::is_object_of_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">kw</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_room</span><span class="plain-syntax">))) &amp;&amp;</span>
<span class="plain-syntax">        (</span><span class="identifier-syntax">Kinds::Behaviour::is_object_of_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">k</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_room</span><span class="plain-syntax">)))</span>
<span class="plain-syntax">        </span><a href="3-si.html#SP3" class="function-link"><span class="function-syntax">SpatialInferences::infer_is_room</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">Instances::as_subject</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">), </span><span class="identifier-syntax">CERTAIN_CE</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>&#167;6. </b>Nothing in the core Inform language prevents room from being made a kind
of vehicle, and so on, but this would cause mayhem in the model world. So:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Spatial::set_subkind_notify</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">Spatial::set_subkind_notify</span></span>:<br/><a href="3-sm.html#SP1">&#167;1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sub</span><span class="plain-syntax">, </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">super</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">sub</span><span class="plain-syntax"> == </span><span class="identifier-syntax">K_thing</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">super</span><span class="plain-syntax"> != </span><span class="identifier-syntax">K_object</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">problem_count</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_ThingAdrift</span><span class="plain-syntax">),</span>
<span class="plain-syntax">                </span><span class="string-syntax">"'thing' is not allowed to be a kind of anything (other than "</span>
<span class="plain-syntax">                </span><span class="string-syntax">"'object')"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">                </span><span class="string-syntax">"because it's too fundamental to the way Inform uses rooms "</span>
<span class="plain-syntax">                </span><span class="string-syntax">"and things to model the physical world."</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">sub</span><span class="plain-syntax"> == </span><span class="identifier-syntax">K_room</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">super</span><span class="plain-syntax"> != </span><span class="identifier-syntax">K_object</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">problem_count</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_RoomAdrift</span><span class="plain-syntax">),</span>
<span class="plain-syntax">                </span><span class="string-syntax">"'room' is not allowed to be a kind of anything (other than "</span>
<span class="plain-syntax">                </span><span class="string-syntax">"'object')"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">                </span><span class="string-syntax">"because it's too fundamental to the way Inform uses rooms "</span>
<span class="plain-syntax">                </span><span class="string-syntax">"and things to model the physical world."</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (((</span><span class="identifier-syntax">sub</span><span class="plain-syntax"> == </span><span class="identifier-syntax">K_container</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">super</span><span class="plain-syntax"> == </span><span class="identifier-syntax">K_supporter</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax">        ((</span><span class="identifier-syntax">sub</span><span class="plain-syntax"> == </span><span class="identifier-syntax">K_supporter</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">super</span><span class="plain-syntax"> == </span><span class="identifier-syntax">K_container</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">problem_count</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_ContainerAdrift</span><span class="plain-syntax">),</span>
<span class="plain-syntax">                </span><span class="string-syntax">"'container' and 'supporter' are not allowed to be kinds "</span>
<span class="plain-syntax">                </span><span class="string-syntax">"of each other"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">                </span><span class="string-syntax">"because they're too fundamental to the way Inform models the "</span>
<span class="plain-syntax">                </span><span class="string-syntax">"physical world. Both are kinds of 'thing', but they are "</span>
<span class="plain-syntax">                </span><span class="string-syntax">"different, and no object is allowed to belong to both at once."</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>&#167;7. </b>This tests whether an object is an instance of "room":
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Spatial::object_is_a_room</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">Spatial::object_is_a_room</span></span>:<br/><a href="3-sm.html#SP27">&#167;27</a>, <a href="3-sm.html#SP31_3_2">&#167;31.3.2</a>, <a href="3-sm.html#SP31_3_3">&#167;31.3.3</a>, <a href="3-sm.html#SP32">&#167;32</a>, <a href="3-sm.html#SP41">&#167;41</a><br/>The Player - <a href="3-tp.html#SP13_1">&#167;13.1</a>, <a href="3-tp.html#SP13_3">&#167;13.3</a><br/>Regions - <a href="3-rgn.html#SP7">&#167;7</a><br/>The Map - <a href="3-tm.html#SP33_1">&#167;33.1</a>, <a href="3-tm.html#SP33_2">&#167;33.2</a>, <a href="3-tm.html#SP33_4">&#167;33.4</a><br/>Mapping Hint Requests - <a href="3-mhr.html#SP11_2">&#167;11.2</a>, <a href="3-mhr.html#SP11_4_1">&#167;11.4.1</a>, <a href="3-mhr.html#SP12">&#167;12</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">K_room</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">I</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Instances::of_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_room</span><span class="plain-syntax">))) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>&#167;8. </b>This is where we give Inform the numbers it needs to write the "a world
with 5 rooms and 27 things"-style text in a successful report on its run.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Spatial::get_world_size</span><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">rooms</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">things</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    *</span><span class="identifier-syntax">rooms</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; *</span><span class="identifier-syntax">things</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_OVER_INSTANCES</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_room</span><span class="plain-syntax">) (*</span><span class="identifier-syntax">rooms</span><span class="plain-syntax">)++;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_OVER_INSTANCES</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_thing</span><span class="plain-syntax">) (*</span><span class="identifier-syntax">things</span><span class="plain-syntax">)++;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>&#167;9. </b>We also need inference subjects to refer to those kinds, but there's a
timing issue with that: the kinds will not exist until Inform's run is fairly
advanced, since they are created by source text. We need the subjects earlier
than that, and so we have to have placeholders until the real thing is ready:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs_room</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="identifier-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs_thing</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="identifier-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs_supporter</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="identifier-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs_person</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
</pre>
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>&#167;10. </b></p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Spatial::create_inference_subjects</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">Spatial::create_inference_subjects</span></span>:<br/><a href="3-sm.html#SP1">&#167;1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">infs_room</span><span class="plain-syntax"> =      </span><span class="identifier-syntax">InferenceSubjects::new_fundamental</span><span class="plain-syntax">(</span><span class="identifier-syntax">global_constants</span><span class="plain-syntax">, </span><span class="string-syntax">"room(early)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">infs_thing</span><span class="plain-syntax"> =     </span><span class="identifier-syntax">InferenceSubjects::new_fundamental</span><span class="plain-syntax">(</span><span class="identifier-syntax">global_constants</span><span class="plain-syntax">, </span><span class="string-syntax">"thing(early)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">infs_supporter</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InferenceSubjects::new_fundamental</span><span class="plain-syntax">(</span><span class="identifier-syntax">global_constants</span><span class="plain-syntax">, </span><span class="string-syntax">"supporter(early)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">infs_person</span><span class="plain-syntax"> =    </span><span class="identifier-syntax">InferenceSubjects::new_fundamental</span><span class="plain-syntax">(</span><span class="identifier-syntax">global_constants</span><span class="plain-syntax">, </span><span class="string-syntax">"person(early)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>&#167;11. </b>And this is where those placeholders give up their places for the real kind
subjects. What happens is that, ordinarily, the machinery creating objects
(and kinds) will allocate a new inference structure for each object, but it
first invites plugins to choose an existing one instead. (The <span class="extract"><span class="extract-syntax">inference_subject</span></span>
structure is rewritten, but pointers to it remain consistent and valid.)
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Spatial::name_to_early_infs</span><button class="popup" onclick="togglePopup('usagePopup7')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup7">Usage of <span class="code-font"><span class="function-syntax">Spatial::name_to_early_infs</span></span>:<br/><a href="3-sm.html#SP1">&#167;1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">inference_subject</span><span class="plain-syntax"> **</span><span class="identifier-syntax">infs</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;notable-spatial-kinds&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;&lt;r&gt;&gt;</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">: </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">K_room</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) *</span><span class="identifier-syntax">infs</span><span class="plain-syntax"> = </span><span class="identifier-syntax">infs_room</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax">: </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">K_thing</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) *</span><span class="identifier-syntax">infs</span><span class="plain-syntax"> = </span><span class="identifier-syntax">infs_thing</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="comment-syntax"> container isn't an early case, surprisingly</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">3</span><span class="plain-syntax">: </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">K_supporter</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) *</span><span class="identifier-syntax">infs</span><span class="plain-syntax"> = </span><span class="identifier-syntax">infs_supporter</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">4</span><span class="plain-syntax">: </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">K_person</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) *</span><span class="identifier-syntax">infs</span><span class="plain-syntax"> = </span><span class="identifier-syntax">infs_person</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>&#167;12. Properties of interest.</b></p>

<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">property</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P_initial_appearance</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="identifier-syntax">property</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P_wearable</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="identifier-syntax">property</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P_fixed_in_place</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>

<span class="identifier-syntax">property</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P_component_parent</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="identifier-syntax">property</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P_component_child</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="identifier-syntax">property</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P_component_sibling</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="identifier-syntax">property</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P_worn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="identifier-syntax">property</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P_mark_as_room</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="identifier-syntax">property</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P_mark_as_thing</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="identifier-syntax">property</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P_container</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="identifier-syntax">property</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P_supporter</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="identifier-syntax">property</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P_matching_key</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
</pre>
<p class="commentary firstcommentary"><a id="SP13" class="paragraph-anchor"></a><b>&#167;13. </b>These are property names to do with spatial layout which Inform provides
special support for; it recognises the English names when they are defined by
the Standard Rules. (So there is no need to translate this to other languages.)
</p>

<p class="commentary">"Matching key" has to appear in here because it both has a traditional I6
name and is used as relation storage. If we didn't care about it being
called <span class="extract"><span class="extract-syntax">with_key</span></span> in the I6 source code, we wouldn't need to do anything
special with it at all.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="function-syntax">&lt;notable-spatial-properties&gt;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">initial</span><span class="plain-syntax"> </span><span class="identifier-syntax">appearance</span><span class="plain-syntax"> |</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">wearable</span><span class="plain-syntax"> |</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">fixed</span><span class="plain-syntax"> </span><span class="identifier-syntax">in</span><span class="plain-syntax"> </span><span class="identifier-syntax">place</span><span class="plain-syntax"> |</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">matching</span><span class="plain-syntax"> </span><span class="identifier-syntax">key</span>
</pre>
<p class="commentary firstcommentary"><a id="SP14" class="paragraph-anchor"></a><b>&#167;14. </b></p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Spatial::new_property_notify</span><button class="popup" onclick="togglePopup('usagePopup8')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup8">Usage of <span class="code-font"><span class="function-syntax">Spatial::new_property_notify</span></span>:<br/><a href="3-sm.html#SP1">&#167;1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">property</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prn</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;notable-spatial-properties&gt;(prn-&gt;</span><span class="element-syntax">name</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;&lt;r&gt;&gt;</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">: </span><span class="identifier-syntax">P_initial_appearance</span><span class="plain-syntax"> = </span><span class="identifier-syntax">prn</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax">: </span><span class="identifier-syntax">P_wearable</span><span class="plain-syntax"> = </span><span class="identifier-syntax">prn</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span><span class="plain-syntax">: </span><span class="identifier-syntax">P_fixed_in_place</span><span class="plain-syntax"> = </span><span class="identifier-syntax">prn</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">3</span><span class="plain-syntax">: </span><span class="identifier-syntax">P_matching_key</span><span class="plain-syntax"> = </span><span class="identifier-syntax">prn</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">Properties::set_translation</span><span class="plain-syntax">(</span><span class="identifier-syntax">P_matching_key</span><span class="plain-syntax">, </span><span class="identifier-syntax">U</span><span class="string-syntax">"with_key"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP15" class="paragraph-anchor"></a><b>&#167;15. Spatial data on instances.</b>Every inference subject contains a pointer to its own unique copy of the
following structure, though we really only use it for instance subjects,
which correspond to the objects in the world model.
</p>

<p class="commentary">An important concept here is the "progenitor" of something in the model,
which may be <span class="extract"><span class="extract-syntax">NULL</span></span>: the "progenitor" is the object which immediately contains,
carries, wears, supports or incorporates it.
</p>

<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">) </span><span class="identifier-syntax">FEATURE_DATA_ON_INSTANCE</span><span class="plain-syntax">(</span><span class="identifier-syntax">spatial</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="plain-syntax">)</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">spatial_data</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">    </span><span class="comment-syntax"> fundamental spatial information about an object's location</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">progenitor</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">progenitor_set_at</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">part_flag</span><span class="plain-syntax">; </span><span class="comment-syntax"> is this a component part of something else?</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">here_flag</span><span class="plain-syntax">; </span><span class="comment-syntax"> was this declared simply as being "here"?</span>

<span class="plain-syntax">    </span><span class="comment-syntax"> temporary storage needed when compiling spatial data to Inter</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">object_tree_parent</span><span class="plain-syntax">; </span><span class="comment-syntax"> in/on/worn by/carried by tree structure</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">object_tree_child</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">object_tree_sibling</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">incorp_tree_parent</span><span class="plain-syntax">; </span><span class="comment-syntax"> part-of tree structure</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">incorp_tree_child</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">incorp_tree_sibling</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">definition_depth</span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">spatial_data</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure spatial_data is private to this section.</li></ul>
<p class="commentary firstcommentary"><a id="SP16" class="paragraph-anchor"></a><b>&#167;16. </b>The attachment of this data is done here:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Spatial::new_subject_notify</span><button class="popup" onclick="togglePopup('usagePopup9')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup9">Usage of <span class="code-font"><span class="function-syntax">Spatial::new_subject_notify</span></span>:<br/><a href="3-sm.html#SP1">&#167;1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">subj</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">spatial_data</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sd</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">spatial_data</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">sd</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">progenitor</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">sd</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">progenitor_set_at</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">sd</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">part_flag</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">; </span><span class="identifier-syntax">sd</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">here_flag</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">sd</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">object_tree_parent</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">sd</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">object_tree_child</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">sd</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">object_tree_sibling</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">sd</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">incorp_tree_child</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">sd</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">incorp_tree_sibling</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">sd</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">incorp_tree_parent</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">sd</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">definition_depth</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">ATTACH_FEATURE_DATA_TO_SUBJECT</span><span class="plain-syntax">(</span><span class="identifier-syntax">spatial</span><span class="plain-syntax">, </span><span class="identifier-syntax">subj</span><span class="plain-syntax">, </span><span class="identifier-syntax">sd</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP17" class="paragraph-anchor"></a><b>&#167;17. </b>Spatial gets to decide here what raw text following a new object will be
taken to mean: for scenery it will be the "description" (i.e., the text
produced on examining), for any other thing it will be the "initial
appearance".
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Spatial::default_appearance</span><button class="popup" onclick="togglePopup('usagePopup10')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup10">Usage of <span class="code-font"><span class="function-syntax">Spatial::default_appearance</span></span>:<br/><a href="3-sm.html#SP1">&#167;1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</span><span class="plain-syntax">, </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">txt</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">InferenceSubjects::is_within</span><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">, </span><span class="identifier-syntax">KindSubjects::from_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_object</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">property</span><span class="plain-syntax"> *</span><span class="identifier-syntax">set_prn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">P_description</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">InferenceSubjects::is_within</span><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">, </span><span class="identifier-syntax">KindSubjects::from_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_thing</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InstanceSubjects::to_object_instance</span><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">I</span><span class="plain-syntax">) &amp;&amp; (</span><a href="3-bck.html#SP7" class="function-link"><span class="function-syntax">Backdrops::object_is_scenery</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">inference</span><span class="plain-syntax"> *</span><span class="identifier-syntax">inf</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">KNOWLEDGE_LOOP</span><span class="plain-syntax">(</span><span class="identifier-syntax">inf</span><span class="plain-syntax">, </span><span class="identifier-syntax">infs</span><span class="plain-syntax">, </span><span class="identifier-syntax">property_inf</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">                    </span><span class="identifier-syntax">property</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">PropertyInferences::get_property</span><span class="plain-syntax">(</span><span class="identifier-syntax">inf</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (((</span><span class="identifier-syntax">prn</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Inferences::get_certainty</span><span class="plain-syntax">(</span><span class="identifier-syntax">inf</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">)) &amp;&amp;</span>
<span class="plain-syntax">                        (</span><span class="identifier-syntax">prn</span><span class="plain-syntax"> == </span><span class="identifier-syntax">P_description</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">                        </span><span class="named-paragraph-container code-font"><a href="3-sm.html#SP17_1" class="named-paragraph-link"><span class="named-paragraph">Produce a problem for doubly described scenery</span><span class="named-paragraph-number">17.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">                        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                    }</span>
<span class="plain-syntax">                }</span>
<span class="plain-syntax">            } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">set_prn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">P_initial_appearance</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">ValueProperties::assert</span><span class="plain-syntax">(</span><span class="identifier-syntax">set_prn</span><span class="plain-syntax">, </span><span class="identifier-syntax">infs</span><span class="plain-syntax">, </span><span class="identifier-syntax">txt</span><span class="plain-syntax">, </span><span class="identifier-syntax">CERTAIN_CE</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP17_1" class="paragraph-anchor"></a><b>&#167;17.1. </b>A lone string as a sentence is a description for a room, but an initial
description for an object. Only now can we know which, since we have only
just decided whether <span class="extract"><span class="extract-syntax">I</span></span> is a room or not. We therefore draw the necessary
inference.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Produce a problem for doubly described scenery</span><span class="named-paragraph-number">17.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">StandardProblems::object_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_SceneryDoublyDescribed</span><span class="plain-syntax">),</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">I</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="string-syntax">"is scenery, which means that it cannot sensibly have any 'initial "</span>
<span class="plain-syntax">        </span><span class="string-syntax">"appearance' property - being scenery, it isn't announced when the "</span>
<span class="plain-syntax">        </span><span class="string-syntax">"player first sees it. That means the quoted text about it has to "</span>
<span class="plain-syntax">        </span><span class="string-syntax">"be read as its 'description' instead, seen when the player examines "</span>
<span class="plain-syntax">        </span><span class="string-syntax">"it. But the source text writes out its description, too"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="string-syntax">"which means we have a subtle little contradiction here."</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-sm.html#SP17">&#167;17</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP18" class="paragraph-anchor"></a><b>&#167;18. Composite noun-quantifiers.</b>Words like "something" or "everywhere" combine a common noun &mdash; thing,
and implicitly room &mdash; with a determiner &mdash; one thing, all rooms.
</p>

<p class="commentary">"Nothing" is conspicuously absent from the possibilities below. It gets
special treatment elsewhere since it can also double as a value (the "not
an object" pseudo-value).
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="function-syntax">&lt;spatial-specifying-nouns&gt;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">_something</span><span class="plain-syntax">/</span><span class="identifier-syntax">anything</span><span class="plain-syntax"> *** |</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">_somewhere</span><span class="plain-syntax">/</span><span class="identifier-syntax">anywhere</span><span class="plain-syntax"> *** |</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">_someone</span><span class="plain-syntax">/</span><span class="identifier-syntax">anyone</span><span class="plain-syntax">/</span><span class="identifier-syntax">somebody</span><span class="plain-syntax">/</span><span class="identifier-syntax">anybody</span><span class="plain-syntax"> *** |</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">_everything</span><span class="plain-syntax"> *** |</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">_everywhere</span><span class="plain-syntax"> *** |</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">_everyone</span><span class="plain-syntax">/</span><span class="identifier-syntax">everybody</span><span class="plain-syntax"> *** |</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">_nowhere</span><span class="plain-syntax"> *** |</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">_nobody</span><span class="plain-syntax">/</span><span class="identifier-syntax">no</span><span class="plain-syntax">-</span><span class="identifier-syntax">one</span><span class="plain-syntax"> *** |</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">_no</span><span class="plain-syntax"> </span><span class="identifier-syntax">_one</span><span class="plain-syntax"> ***</span>
</pre>
<p class="commentary firstcommentary"><a id="SP19" class="paragraph-anchor"></a><b>&#167;19. </b>When we detect them, we set both <span class="extract"><span class="extract-syntax">quantifier_used</span></span> and <span class="extract"><span class="extract-syntax">some_kind</span></span>
appropriately. None can be recognised if the basic kinds are not created yet,
which we check for by inspecting <span class="extract"><span class="extract-syntax">K_thing</span></span>. (Note that the S-parser may indeed
be asked to parse "something" before this point, as when it scans the domains
of adjective definitions, but that it's okay that it produces a null result.)
</p>

<p class="commentary">With the "some-" words, no quantifier is set because the meaning here is the
<span class="extract"><span class="extract-syntax">exists_quantifier</span></span>. Since this is the default behaviour for unquantified
descriptions anyway &mdash; "a door is in the Great Hall" means that such a door
exists &mdash; we needn't set the variable.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Spatial::parse_composite_NQs</span><button class="popup" onclick="togglePopup('usagePopup11')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup11">Usage of <span class="code-font"><span class="function-syntax">Spatial::parse_composite_NQs</span></span>:<br/><a href="3-sm.html#SP1">&#167;1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">wording</span><span class="plain-syntax"> *</span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> *</span><span class="identifier-syntax">DW</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">quantifier</span><span class="plain-syntax"> **</span><span class="identifier-syntax">quant</span><span class="plain-syntax">, </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> **</span><span class="identifier-syntax">some_kind</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">K_thing</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="function-syntax">&lt;&lt;quantifier:q&gt;&gt;</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;spatial-specifying-nouns&gt;</span><span class="plain-syntax">(*</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">            *</span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Wordings::from</span><span class="plain-syntax">(*</span><span class="identifier-syntax">W</span><span class="plain-syntax">,</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;spatial-specifying-nouns&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">)));</span>
<span class="plain-syntax">            *</span><span class="identifier-syntax">quant</span><span class="plain-syntax"> = </span><span class="function-syntax">&lt;&lt;quantifier:q&gt;&gt;</span><span class="plain-syntax">; *</span><span class="identifier-syntax">some_kind</span><span class="plain-syntax"> = </span><span class="function-syntax">&lt;&lt;rp&gt;&gt;</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP20" class="paragraph-anchor"></a><b>&#167;20. Nowhere.</b>This means the same as "nothing", in a noun context, but we annotate a parse
node using this wording in order to produce better problem messages if need be.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="function-syntax">&lt;notable-spatial-noun-phrases&gt;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">nowhere</span>
</pre>
<p class="commentary firstcommentary"><a id="SP21" class="paragraph-anchor"></a><b>&#167;21. </b></p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Spatial::act_on_special_NPs</span><button class="popup" onclick="togglePopup('usagePopup12')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup12">Usage of <span class="code-font"><span class="function-syntax">Spatial::act_on_special_NPs</span></span>:<br/><a href="3-sm.html#SP1">&#167;1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="function-syntax">&lt;notable-spatial-noun-phrases&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">))) &amp;&amp;</span>
<span class="plain-syntax">        (</span><span class="identifier-syntax">Word::unexpectedly_upper_case</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">))) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax">        (</span><span class="identifier-syntax">K_room</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Refiner::give_spec_to_noun</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">Rvalues::new_nothing_object_constant</span><span class="plain-syntax">());</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Annotations::write_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">nowhere_ANNOT</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP22" class="paragraph-anchor"></a><b>&#167;22. </b>Now in fact this often does get picked up:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Spatial::intervene_in_assertion</span><button class="popup" onclick="togglePopup('usagePopup13')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup13">Usage of <span class="code-font"><span class="function-syntax">Spatial::intervene_in_assertion</span></span>:<br/><a href="3-sm.html#SP1">&#167;1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">px</span><span class="plain-syntax">, </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">py</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Annotations::read_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">py</span><span class="plain-syntax">, </span><span class="identifier-syntax">nowhere_ANNOT</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">left_subject</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_subject</span><span class="plain-syntax">(</span><span class="identifier-syntax">px</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">left_subject</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">KindSubjects::to_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">left_subject</span><span class="plain-syntax">))</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">StandardProblems::subject_problem_at_sentence</span><span class="plain-syntax">(</span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_KindNowhere</span><span class="plain-syntax">),</span>
<span class="plain-syntax">                    </span><span class="identifier-syntax">left_subject</span><span class="plain-syntax">,</span>
<span class="plain-syntax">                    </span><span class="string-syntax">"seems to be said to be 'nowhere' in some way"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">                    </span><span class="string-syntax">"which doesn't make sense. An individual thing can be 'nowhere', "</span>
<span class="plain-syntax">                    </span><span class="string-syntax">"but here we're talking about a whole kind, and it's not allowed "</span>
<span class="plain-syntax">                    </span><span class="string-syntax">"to talk about general locations of a whole kind of things at once."</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">Assert::true_about</span><span class="plain-syntax">(</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">Propositions::Abstract::to_put_nowhere</span><span class="plain-syntax">(), </span><span class="identifier-syntax">left_subject</span><span class="plain-syntax">, </span><span class="identifier-syntax">prevailing_mood</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP23" class="paragraph-anchor"></a><b>&#167;23. Here.</b>A sentence like "The sonic screwdriver is here." is not copular, but instead
expresses a relationship &mdash; "here" is not a value but a relation to an
unstated object. That object is the room we're currently talking about, which
sounds easy to work out, but isn't: we don't yet know which of the objects
being talked about will eventually turn out to be rooms. As a result, "here"
needs delicate handling, and its own inference type.
</p>

<p class="commentary">The fact that rooms cannot be "here" is useful, because it means Inform can
with certainty read
</p>

<blockquote>
    <p>The washing machine is here. The shirt is in the machine.</p>
</blockquote>

<p class="commentary">as creating a container called "washing machine", not a room.
</p>

<p class="commentary firstcommentary"><a id="SP24" class="paragraph-anchor"></a><b>&#167;24. </b></p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Spatial::infer_presence_here</span><button class="popup" onclick="togglePopup('usagePopup14')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup14">Usage of <span class="code-font"><span class="function-syntax">Spatial::infer_presence_here</span></span>:<br/>Everywhere, Nowhere and Here - <a href="3-enah.html#SP9">&#167;9</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Instances::as_subject</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">inference</span><span class="plain-syntax"> *</span><span class="identifier-syntax">inf</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">POSITIVE_KNOWLEDGE_LOOP</span><span class="plain-syntax">(</span><span class="identifier-syntax">inf</span><span class="plain-syntax">, </span><span class="identifier-syntax">infs</span><span class="plain-syntax">, </span><span class="identifier-syntax">parentage_here_inf</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">StandardProblems::contradiction_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_DuplicateHere</span><span class="plain-syntax">),</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">Inferences::where_inferred</span><span class="plain-syntax">(</span><span class="identifier-syntax">inf</span><span class="plain-syntax">),</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">,</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">I</span><span class="plain-syntax">,</span>
<span class="plain-syntax">            </span><span class="string-syntax">"can only be said to be 'here' once"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">            </span><span class="string-syntax">"in a single assertion sentence. This avoids potential confusion, "</span>
<span class="plain-syntax">            </span><span class="string-syntax">"since 'here' can mean different things in different sentences."</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><a href="3-si.html#SP6" class="function-link"><span class="function-syntax">SpatialInferences::infer_parentage_here</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">, </span><span class="identifier-syntax">CERTAIN_CE</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Anaphora::get_current_subject</span><span class="plain-syntax">());</span>
<span class="plain-syntax">    </span><a href="3-si.html#SP3" class="function-link"><span class="function-syntax">SpatialInferences::infer_is_room</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">, </span><span class="identifier-syntax">IMPOSSIBLE_CE</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP25" class="paragraph-anchor"></a><b>&#167;25. </b>Similarly:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Spatial::infer_presence_nowhere</span><button class="popup" onclick="togglePopup('usagePopup15')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup15">Usage of <span class="code-font"><span class="function-syntax">Spatial::infer_presence_nowhere</span></span>:<br/>Everywhere, Nowhere and Here - <a href="3-enah.html#SP8">&#167;8</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><a href="3-si.html#SP7" class="function-link"><span class="function-syntax">SpatialInferences::infer_is_nowhere</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">Instances::as_subject</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">), </span><span class="identifier-syntax">CERTAIN_CE</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="3-si.html#SP3" class="function-link"><span class="function-syntax">SpatialInferences::infer_is_room</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">Instances::as_subject</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">), </span><span class="identifier-syntax">IMPOSSIBLE_CE</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP26" class="paragraph-anchor"></a><b>&#167;26. Completing the world model.</b>That's enough preliminaries; time to get on with adding a sense of space
to the model world.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Spatial::IF_complete_model</span><button class="popup" onclick="togglePopup('usagePopup16')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup16">Usage of <span class="code-font"><span class="function-syntax">Spatial::IF_complete_model</span></span>:<br/><a href="3-sm.html#SP1">&#167;1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">stage</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">switch</span><span class="plain-syntax">(</span><span class="identifier-syntax">stage</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax">: </span><a href="3-sm.html#SP27" class="function-link"><span class="function-syntax">Spatial::spatial_stage_I</span></a><span class="plain-syntax">(); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span><span class="plain-syntax">: </span><a href="3-sm.html#SP31" class="function-link"><span class="function-syntax">Spatial::spatial_stage_II</span></a><span class="plain-syntax">(); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">3</span><span class="plain-syntax">: </span><a href="3-sm.html#SP38" class="function-link"><span class="function-syntax">Spatial::spatial_stage_III</span></a><span class="plain-syntax">(); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">4</span><span class="plain-syntax">: </span><a href="3-sm.html#SP41" class="function-link"><span class="function-syntax">Spatial::spatial_stage_IV</span></a><span class="plain-syntax">(); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">5</span><span class="plain-syntax">: </span><a href="3-sm.html#SP42" class="function-link"><span class="function-syntax">Spatial::spatial_stage_V</span></a><span class="plain-syntax">(); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP27" class="paragraph-anchor"></a><b>&#167;27. </b>Recall that as we begin stage I of model creation, all objects are, of
course, created, and they have kinds associated with them if the source
text has said explicitly what kind they have: but that is not good enough.
It often happens that the source implicitly specifies a kind, and we need
to take note. If X is in Y, then Y might be a room, or a region, or a
container, and we might need to look at other sentences &mdash; say, establishing
that Y is the destination of a map connection &mdash; to see which.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">implied_Stage_room</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>

<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Spatial::spatial_stage_I</span><button class="popup" onclick="togglePopup('usagePopup17')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup17">Usage of <span class="code-font"><span class="function-syntax">Spatial::spatial_stage_I</span></span>:<br/><a href="3-sm.html#SP26">&#167;26</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax">, *</span><span class="identifier-syntax">potential_stage_room</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">potential_stage_room_kind</span><span class="plain-syntax"> = </span><span class="identifier-syntax">K_thing</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">potential_stage_room_kind_at</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_OVER_INSTANCES</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_object</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="named-paragraph-container code-font"><a href="3-sm.html#SP27_2" class="named-paragraph-link"><span class="named-paragraph">Perform kind determination for this object</span><span class="named-paragraph-number">27.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">count</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_OVER_INSTANCES</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_object</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-sm.html#SP7" class="function-link"><span class="function-syntax">Spatial::object_is_a_room</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">))</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">count</span><span class="plain-syntax">++;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">count</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="3-sm.html#SP27_1" class="named-paragraph-link"><span class="named-paragraph">Create an implied room</span><span class="named-paragraph-number">27.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">potential_stage_room</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">KIND_CHANGES</span><span class="plain-syntax">, </span><span class="string-syntax">"Setting kind of potential implied room $O as %u\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">potential_stage_room</span><span class="plain-syntax">, </span><span class="identifier-syntax">potential_stage_room_kind</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Propositions::Abstract::assert_kind_of_instance</span><span class="plain-syntax">(</span><span class="identifier-syntax">potential_stage_room</span><span class="plain-syntax">, </span><span class="identifier-syntax">potential_stage_room_kind</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP28" class="paragraph-anchor"></a><b>&#167;28. </b></p>

<pre class="displayed-code all-displayed-code code-font">
<span class="function-syntax">&lt;implied-room-name&gt;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">stage</span>
</pre>
<p class="commentary firstcommentary"><a id="SP27_1" class="paragraph-anchor"></a><b>&#167;27.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Create an implied room</span><span class="named-paragraph-number">27.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">potential_stage_room</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">potential_stage_room_kind</span><span class="plain-syntax"> != </span><span class="identifier-syntax">K_container</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax">            (</span><span class="identifier-syntax">potential_stage_room_kind</span><span class="plain-syntax"> != </span><span class="identifier-syntax">K_room</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">potential_stage_room_kind_at</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">StandardProblems::object_problem_at_sentence</span><span class="plain-syntax">(</span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_StageNotRoomable</span><span class="plain-syntax">),</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">potential_stage_room</span><span class="plain-syntax">,</span>
<span class="plain-syntax">                </span><span class="string-syntax">"is called 'Stage' and is in a story with no declared rooms, "</span>
<span class="plain-syntax">                </span><span class="string-syntax">"so I think it ought to be the room in which everything happens. "</span>
<span class="plain-syntax">                </span><span class="string-syntax">"However, that seems to be contradicted by this sentence"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">                </span><span class="string-syntax">"which implies that 'Stage' definitely isn't a room."</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">potential_stage_room_kind</span><span class="plain-syntax"> = </span><span class="identifier-syntax">K_room</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">implied_Stage_room</span><span class="plain-syntax"> = </span><span class="identifier-syntax">potential_stage_room</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Feeds::feed_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"Stage"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">pcalc_prop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prop</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Propositions::Abstract::to_create_something</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_room</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Assert::true</span><span class="plain-syntax">(</span><span class="identifier-syntax">prop</span><span class="plain-syntax">, </span><span class="identifier-syntax">CERTAIN_CE</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">implied_Stage_room</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Instances::latest</span><span class="plain-syntax">();</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">parsed_use_option_setting</span><span class="plain-syntax"> *</span><span class="identifier-syntax">puos</span><span class="plain-syntax"> =</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">UseOptions::force_setting</span><span class="plain-syntax">(</span><span class="identifier-syntax">NAMELESS_ROOM_DESCRIPTIONS_UO</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">puos</span><span class="plain-syntax">) </span><span class="identifier-syntax">NewUseOptions::set</span><span class="plain-syntax">(</span><span class="identifier-syntax">puos</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-sm.html#SP27">&#167;27</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP27_2" class="paragraph-anchor"></a><b>&#167;27.2. </b>Our main problem in what follows is caused by "in" being so ambiguous,
or perhaps it might be said that the real problem is that we choose to
distinguish between rooms and containers on a world-modelling level &mdash; when it
could well be argued that they are linguistically the same thing.
</p>

<p class="commentary">It means that Inform is often reading code such as:
</p>

<blockquote>
    <p>The croquet ball is in the Boxed Set.</p>
</blockquote>

<p class="commentary">and not being sure whether "Boxed Set" is a container or a room.
</p>

<p class="commentary">In the following determination, we use two sources of information. One is explicit
data given by the source text or unambiguously implied in it, like so &mdash;
</p>

<blockquote>
    <p>The Boxed Set is a container. The spoon is on the low table.</p>
</blockquote>

<p class="commentary">which tell us the Boxed Set is certainly a container and the table certainly
a supporter. This information about an object is the "designer choice" about
its kind.
</p>

<p class="commentary">The other source of information comes from less definite sentences using words
like "in", and from the spatial context in which the object appears. This
is the "geography choice" for its kind.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Perform kind determination for this object</span><span class="named-paragraph-number">27.2</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Instances::get_creating_sentence</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">designers_choice</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="3-sm.html#SP27_2_1" class="named-paragraph-link"><span class="named-paragraph">Determine the designer choice</span><span class="named-paragraph-number">27.2.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="function-syntax">&lt;implied-room-name&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">Instances::get_name</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">))) &amp;&amp;</span>
<span class="plain-syntax">        (</span><span class="identifier-syntax">potential_stage_room</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">potential_stage_room</span><span class="plain-syntax"> = </span><span class="identifier-syntax">I</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">designers_choice</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">potential_stage_room_kind</span><span class="plain-syntax"> = </span><span class="identifier-syntax">designers_choice</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">potential_stage_room_kind_at</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Instances::get_kind_set_sentence</span><span class="plain-syntax">(</span><span class="identifier-syntax">potential_stage_room</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">geography_choice</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">inference</span><span class="plain-syntax"> *</span><span class="identifier-syntax">geography_inference</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">geography_certainty</span><span class="plain-syntax"> = </span><span class="identifier-syntax">UNKNOWN_CE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="3-sm.html#SP27_2_2" class="named-paragraph-link"><span class="named-paragraph">Determine the geography choice</span><span class="named-paragraph-number">27.2.2</span></a></span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">geography_choice</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax">        (</span><span class="identifier-syntax">Kinds::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">geography_choice</span><span class="plain-syntax">, </span><span class="identifier-syntax">designers_choice</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">))</span>
<span class="plain-syntax">        </span><span class="named-paragraph-container code-font"><a href="3-sm.html#SP27_2_3" class="named-paragraph-link"><span class="named-paragraph">Attempt to reconcile the two choices</span><span class="named-paragraph-number">27.2.3</span></a></span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">I</span><span class="plain-syntax"> != </span><span class="identifier-syntax">potential_stage_room</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax">        (</span><span class="identifier-syntax">Kinds::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">Instances::to_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">), </span><span class="identifier-syntax">K_object</span><span class="plain-syntax">)))</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Propositions::Abstract::assert_kind_of_instance</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_thing</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-sm.html#SP27">&#167;27</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP27_2_1" class="paragraph-anchor"></a><b>&#167;27.2.1. </b>By this point, any explicit information is reflected in the hierarchy of
kinds. We look out for four specialised kinds of thing, but failing that,
we simply take its broadest kind &mdash; usually "thing", "room", "direction"
or "region".
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Determine the designer choice</span><span class="named-paragraph-number">27.2.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">f</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">infs</span><span class="plain-syntax"> = </span><span class="identifier-syntax">KindSubjects::from_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">Instances::to_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">));</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">infs</span><span class="plain-syntax">; </span><span class="identifier-syntax">infs</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InferenceSubjects::narrowest_broader_subject</span><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><span class="identifier-syntax">KindSubjects::to_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::Behaviour::is_subkind_of_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">f</span><span class="plain-syntax"> = </span><span class="identifier-syntax">K</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Kinds::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">f</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_container</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax">                (</span><span class="identifier-syntax">Kinds::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">f</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_supporter</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax">                (</span><span class="identifier-syntax">Kinds::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">f</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_door</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax">                (</span><span class="identifier-syntax">Kinds::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">f</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_person</span><span class="plain-syntax">)))</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">designers_choice</span><span class="plain-syntax"> = </span><span class="identifier-syntax">f</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">designers_choice</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">designers_choice</span><span class="plain-syntax"> = </span><span class="identifier-syntax">f</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-sm.html#SP27_2">&#167;27.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP27_2_2" class="paragraph-anchor"></a><b>&#167;27.2.2. </b>If there is any positive information that this is a room, that's the
geography choice; otherwise it's whichever of room or container is more
probably suggested by inferences.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Determine the geography choice</span><span class="named-paragraph-number">27.2.2</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">inference</span><span class="plain-syntax"> *</span><span class="identifier-syntax">inf</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">KNOWLEDGE_LOOP</span><span class="plain-syntax">(</span><span class="identifier-syntax">inf</span><span class="plain-syntax">, </span><span class="identifier-syntax">Instances::as_subject</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">), </span><span class="identifier-syntax">contains_things_inf</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Inferences::get_certainty</span><span class="plain-syntax">(</span><span class="identifier-syntax">inf</span><span class="plain-syntax">) &gt; </span><span class="identifier-syntax">geography_certainty</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">geography_choice</span><span class="plain-syntax"> = </span><span class="identifier-syntax">K_container</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">geography_certainty</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Inferences::get_certainty</span><span class="plain-syntax">(</span><span class="identifier-syntax">inf</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">geography_inference</span><span class="plain-syntax"> = </span><span class="identifier-syntax">inf</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">KNOWLEDGE_LOOP</span><span class="plain-syntax">(</span><span class="identifier-syntax">inf</span><span class="plain-syntax">, </span><span class="identifier-syntax">Instances::as_subject</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">), </span><span class="identifier-syntax">is_room_inf</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Inferences::get_certainty</span><span class="plain-syntax">(</span><span class="identifier-syntax">inf</span><span class="plain-syntax">) &gt; </span><span class="identifier-syntax">UNKNOWN_CE</span><span class="plain-syntax">) ||</span>
<span class="plain-syntax">            (</span><span class="identifier-syntax">Inferences::get_certainty</span><span class="plain-syntax">(</span><span class="identifier-syntax">inf</span><span class="plain-syntax">) &gt; </span><span class="identifier-syntax">geography_certainty</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">geography_choice</span><span class="plain-syntax"> = </span><span class="identifier-syntax">K_room</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">geography_certainty</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Inferences::get_certainty</span><span class="plain-syntax">(</span><span class="identifier-syntax">inf</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">geography_inference</span><span class="plain-syntax"> = </span><span class="identifier-syntax">inf</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-sm.html#SP27_2">&#167;27.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP27_2_3" class="paragraph-anchor"></a><b>&#167;27.2.3. </b>Since the designer choice is the one currently in force, we have basically
three choices here: impose the geography choice instead; do nothing; or issue
a problem message. The case where we do nothing is if geography suggests
something is a room, when it's actually a door: this is because sentences
like "East is the Marble Portal" can suggest the "Marble Portal" is a room
when it's legitimately a door.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Attempt to reconcile the two choices</span><span class="named-paragraph-number">27.2.3</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sentence_setting_kind</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Instances::get_kind_set_sentence</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">designers_choice</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) ||</span>
<span class="plain-syntax">        ((</span><span class="identifier-syntax">geography_certainty</span><span class="plain-syntax"> == </span><span class="identifier-syntax">CERTAIN_CE</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax">            (</span><span class="identifier-syntax">Kinds::Behaviour::is_object_of_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">geography_choice</span><span class="plain-syntax">, </span><span class="identifier-syntax">designers_choice</span><span class="plain-syntax">))))</span>
<span class="plain-syntax">        </span><span class="named-paragraph-container code-font"><a href="3-sm.html#SP27_2_3_1" class="named-paragraph-link"><span class="named-paragraph">Accept the geography choice, since it only refines what we already know</span><span class="named-paragraph-number">27.2.3.1</span></a></span>
<span class="plain-syntax">    </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">geography_certainty</span><span class="plain-syntax"> == </span><span class="identifier-syntax">CERTAIN_CE</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax">            (!((</span><span class="identifier-syntax">Kinds::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">designers_choice</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_door</span><span class="plain-syntax">)) &amp;&amp;</span>
<span class="plain-syntax">                (</span><span class="identifier-syntax">Kinds::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">geography_choice</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_room</span><span class="plain-syntax">)))))</span>
<span class="plain-syntax">        </span><span class="named-paragraph-container code-font"><a href="3-sm.html#SP27_2_3_2" class="named-paragraph-link"><span class="named-paragraph">Issue a problem message, since the choices are irreconcilable</span><span class="named-paragraph-number">27.2.3.2</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-sm.html#SP27_2">&#167;27.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP27_2_3_1" class="paragraph-anchor"></a><b>&#167;27.2.3.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Accept the geography choice, since it only refines what we already know</span><span class="named-paragraph-number">27.2.3.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">I</span><span class="plain-syntax"> == </span><span class="identifier-syntax">potential_stage_room</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">KIND_CHANGES</span><span class="plain-syntax">, </span><span class="string-syntax">"Noting potential geography choice of kind of $O as %u\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">geography_choice</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">potential_stage_room_kind</span><span class="plain-syntax"> = </span><span class="identifier-syntax">geography_choice</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">potential_stage_room_kind_at</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Inferences::where_inferred</span><span class="plain-syntax">(</span><span class="identifier-syntax">geography_inference</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">KIND_CHANGES</span><span class="plain-syntax">, </span><span class="string-syntax">"Accepting geography choice of kind of $O as %u\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">geography_choice</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Propositions::Abstract::assert_kind_of_instance</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">geography_choice</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-sm.html#SP27_2_3">&#167;27.2.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP27_2_3_2" class="paragraph-anchor"></a><b>&#167;27.2.3.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue a problem message, since the choices are irreconcilable</span><span class="named-paragraph-number">27.2.3.2</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"Choices: designer %u, geography %u.\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">designers_choice</span><span class="plain-syntax">, </span><span class="identifier-syntax">geography_choice</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">decider</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Instances::get_creating_sentence</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sentence_setting_kind</span><span class="plain-syntax">) </span><span class="identifier-syntax">decider</span><span class="plain-syntax"> = </span><span class="identifier-syntax">sentence_setting_kind</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">designers_choice</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_person</span><span class="plain-syntax">))</span>
<span class="plain-syntax">        </span><span class="named-paragraph-container code-font"><a href="3-sm.html#SP27_2_3_2_1" class="named-paragraph-link"><span class="named-paragraph">Issue a problem message for implied containment by a person</span><span class="named-paragraph-number">27.2.3.2.1</span></a></span>
<span class="plain-syntax">    </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Kinds::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">designers_choice</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_supporter</span><span class="plain-syntax">)) &amp;&amp;</span>
<span class="plain-syntax">                (</span><span class="identifier-syntax">Kinds::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">geography_choice</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_container</span><span class="plain-syntax">)))</span>
<span class="plain-syntax">        </span><span class="named-paragraph-container code-font"><a href="3-sm.html#SP27_2_3_2_2" class="named-paragraph-link"><span class="named-paragraph">Issue a problem message for simultaneous containment and support</span><span class="named-paragraph-number">27.2.3.2.2</span></a></span>
<span class="plain-syntax">    </span><span class="reserved-syntax">else</span>
<span class="plain-syntax">        </span><span class="named-paragraph-container code-font"><a href="3-sm.html#SP27_2_3_2_3" class="named-paragraph-link"><span class="named-paragraph">Issue a more generic problem message for irreconcilable kinds</span><span class="named-paragraph-number">27.2.3.2.3</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-sm.html#SP27_2_3">&#167;27.2.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP27_2_3_2_1" class="paragraph-anchor"></a><b>&#167;27.2.3.2.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue a problem message for implied containment by a person</span><span class="named-paragraph-number">27.2.3.2.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">StandardProblems::contradiction_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_PersonContaining</span><span class="plain-syntax">),</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">sentence_setting_kind</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Inferences::where_inferred</span><span class="plain-syntax">(</span><span class="identifier-syntax">geography_inference</span><span class="plain-syntax">), </span><span class="identifier-syntax">I</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="string-syntax">"cannot contain or support things like something inanimate"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="string-syntax">"which is what you are implying. Instead, people must carry or wear them: "</span>
<span class="plain-syntax">        </span><span class="string-syntax">"so 'The briefcase is in Daphne.' is disallowed, but 'The briefcase is "</span>
<span class="plain-syntax">        </span><span class="string-syntax">"carried by Daphne.' is fine, or indeed 'Daphne carries the briefcase.'"</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-sm.html#SP27_2_3_2">&#167;27.2.3.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP27_2_3_2_2" class="paragraph-anchor"></a><b>&#167;27.2.3.2.2. </b>A notorious problem message for a notorious limitation of the traditional
Inform spatial model:
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue a problem message for simultaneous containment and support</span><span class="named-paragraph-number">27.2.3.2.2</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">StandardProblems::contradiction_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_CantContainAndSupport</span><span class="plain-syntax">),</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">decider</span><span class="plain-syntax">, </span><span class="identifier-syntax">Inferences::where_inferred</span><span class="plain-syntax">(</span><span class="identifier-syntax">geography_inference</span><span class="plain-syntax">), </span><span class="identifier-syntax">I</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="string-syntax">"cannot both contain things and support things"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="string-syntax">"which is what you're implying here. If you need both, the easiest way is "</span>
<span class="plain-syntax">        </span><span class="string-syntax">"to make it either a supporter with a container attached or vice versa. "</span>
<span class="plain-syntax">        </span><span class="string-syntax">"For instance: 'A desk is here. On the desk is a newspaper. An openable "</span>
<span class="plain-syntax">        </span><span class="string-syntax">"container called the drawer is part of the desk. In the drawer is a "</span>
<span class="plain-syntax">        </span><span class="string-syntax">"stapler.'"</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-sm.html#SP27_2_3_2">&#167;27.2.3.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP27_2_3_2_3" class="paragraph-anchor"></a><b>&#167;27.2.3.2.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue a more generic problem message for irreconcilable kinds</span><span class="named-paragraph-number">27.2.3.2.3</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">StandardProblems::contradiction_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_BothRoomAndSupporter</span><span class="plain-syntax">),</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">decider</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Inferences::where_inferred</span><span class="plain-syntax">(</span><span class="identifier-syntax">geography_inference</span><span class="plain-syntax">), </span><span class="identifier-syntax">I</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="string-syntax">"would need to have two different and incompatible kinds to make both "</span>
<span class="plain-syntax">        </span><span class="string-syntax">"sentences true"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="string-syntax">"and this is a contradiction."</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-sm.html#SP27_2_3_2">&#167;27.2.3.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP29" class="paragraph-anchor"></a><b>&#167;29. </b>Stage II at last. Now the kinds are all known, and it's time to work out
the spatial arrangements. Inform's spatial model assigns every instance object
a unique "progenitor", which may be <span class="extract"><span class="extract-syntax">NULL</span></span>, representing the object which
immediately contains, carries, wears, supports or incorporates it.
</p>

<p class="commentary">Clearly if we know every object's progenitor, then we know the whole spatial
layout &mdash; it's all just elaboration from there. (See Stage III below.) But
since other features can decide on this, not just Spatial, we had better
provide access routines to read and write:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="function-syntax">Spatial::progenitor</span><button class="popup" onclick="togglePopup('usagePopup18')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup18">Usage of <span class="code-font"><span class="function-syntax">Spatial::progenitor</span></span>:<br/><a href="3-sm.html#SP31_2">&#167;31.2</a>, <a href="3-sm.html#SP37">&#167;37</a>, <a href="3-sm.html#SP38_1">&#167;38.1</a>, <a href="3-sm.html#SP38_1_1">&#167;38.1.1</a>, <a href="3-sm.html#SP38_2">&#167;38.2</a>, <a href="3-sm.html#SP38_3">&#167;38.3</a><br/>The Player - <a href="3-tp.html#SP13_3">&#167;13.3</a><br/>Regions - <a href="3-rgn.html#SP7">&#167;7</a><br/>The Map - <a href="3-tm.html#SP33_6">&#167;33.6</a>, <a href="3-tm.html#SP33_7">&#167;33.7</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">I</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">FEATURE_INACTIVE</span><span class="plain-syntax">(</span><span class="identifier-syntax">spatial</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">progenitor</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>

<span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="function-syntax">Spatial::progenitor_set_at</span><span class="plain-syntax">(</span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">I</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">FEATURE_INACTIVE</span><span class="plain-syntax">(</span><span class="identifier-syntax">spatial</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">progenitor_set_at</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>

<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Spatial::set_progenitor</span><button class="popup" onclick="togglePopup('usagePopup19')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup19">Usage of <span class="code-font"><span class="function-syntax">Spatial::set_progenitor</span></span>:<br/><a href="3-sm.html#SP31_3">&#167;31.3</a><br/>The Map - <a href="3-tm.html#SP33_7">&#167;33.7</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">of</span><span class="plain-syntax">, </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">to</span><span class="plain-syntax">, </span><span class="identifier-syntax">inference</span><span class="plain-syntax"> *</span><span class="identifier-syntax">reason</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">FEATURE_INACTIVE</span><span class="plain-syntax">(</span><span class="identifier-syntax">spatial</span><span class="plain-syntax">))</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"spatial feature inactive"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">to</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"set progenitor of nothing"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">of</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">progenitor</span><span class="plain-syntax"> = </span><span class="identifier-syntax">to</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">of</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">progenitor_set_at</span><span class="plain-syntax"> =</span>
<span class="plain-syntax">        (</span><span class="identifier-syntax">reason</span><span class="plain-syntax">)?</span><span class="identifier-syntax">Inferences::where_inferred</span><span class="plain-syntax">(</span><span class="identifier-syntax">reason</span><span class="plain-syntax">):</span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP30" class="paragraph-anchor"></a><b>&#167;30. </b>This is used for error recovery only.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Spatial::void_progenitor</span><button class="popup" onclick="togglePopup('usagePopup20')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup20">Usage of <span class="code-font"><span class="function-syntax">Spatial::void_progenitor</span></span>:<br/><a href="3-sm.html#SP38_1">&#167;38.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">of</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">FEATURE_INACTIVE</span><span class="plain-syntax">(</span><span class="identifier-syntax">spatial</span><span class="plain-syntax">))</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"spatial feature inactive"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">of</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">progenitor</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">of</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">progenitor_set_at</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP31" class="paragraph-anchor"></a><b>&#167;31. </b>We need to establish what the rooms are before we worry about objects which
are "here"; rooms are never "here", so there's no circularity in that,
and we solve this problem by determining the kind of non-here objects before
the kind of here-objects.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Spatial::spatial_stage_II</span><button class="popup" onclick="togglePopup('usagePopup21')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup21">Usage of <span class="code-font"><span class="function-syntax">Spatial::spatial_stage_II</span></span>:<br/><a href="3-sm.html#SP26">&#167;26</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="3-sm.html#SP31_1" class="named-paragraph-link"><span class="named-paragraph">Set the here flag for all those objects whose parentage is only thus known</span><span class="named-paragraph-number">31.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_OVER_INSTANCES</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_object</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">here_flag</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><span class="named-paragraph-container code-font"><a href="3-sm.html#SP31_3" class="named-paragraph-link"><span class="named-paragraph">Position this object spatially</span><span class="named-paragraph-number">31.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_OVER_INSTANCES</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_object</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">here_flag</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><span class="named-paragraph-container code-font"><a href="3-sm.html#SP31_3" class="named-paragraph-link"><span class="named-paragraph">Position this object spatially</span><span class="named-paragraph-number">31.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="3-sm.html#SP31_2" class="named-paragraph-link"><span class="named-paragraph">Issue problem messages if non-physical objects are spatially enclosed</span><span class="named-paragraph-number">31.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP31_1" class="paragraph-anchor"></a><b>&#167;31.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Set the here flag for all those objects whose parentage is only thus known</span><span class="named-paragraph-number">31.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_OVER_INSTANCES</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_object</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">here_flag</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">inference</span><span class="plain-syntax"> *</span><span class="identifier-syntax">inf</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">POSITIVE_KNOWLEDGE_LOOP</span><span class="plain-syntax">(</span><span class="identifier-syntax">inf</span><span class="plain-syntax">, </span><span class="identifier-syntax">Instances::as_subject</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">), </span><span class="identifier-syntax">parentage_here_inf</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">here_flag</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-sm.html#SP31">&#167;31</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP31_2" class="paragraph-anchor"></a><b>&#167;31.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue problem messages if non-physical objects are spatially enclosed</span><span class="named-paragraph-number">31.2</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_OVER_INSTANCES</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_object</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="3-sm.html#SP29" class="function-link"><span class="function-syntax">Spatial::progenitor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">)) &amp;&amp;</span>
<span class="plain-syntax">            (</span><span class="identifier-syntax">Instances::of_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_thing</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax">            (</span><span class="identifier-syntax">Instances::of_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_room</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax">            (</span><a href="3-rgn.html#SP9" class="function-link"><span class="function-syntax">Regions::object_is_a_region</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">Problems::quote_source</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">Instances::get_creating_sentence</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">));</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">Problems::quote_object</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">I</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">Problems::quote_object</span><span class="plain-syntax">(3, </span><a href="3-sm.html#SP29" class="function-link"><span class="function-syntax">Spatial::progenitor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">));</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">Problems::quote_kind</span><span class="plain-syntax">(4, </span><span class="identifier-syntax">Instances::to_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">));</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">StandardProblems::handmade_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_NonThingInModel</span><span class="plain-syntax">));</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax">                </span><span class="string-syntax">"In the sentence %1, you create an object '%2' which you then seem "</span>
<span class="plain-syntax">                </span><span class="string-syntax">"to place in or on or as part of '%3', but the kind of '%2' is %4. "</span>
<span class="plain-syntax">                </span><span class="string-syntax">"Since %4 is not a kind of thing, it follows that %2 is not a thing, "</span>
<span class="plain-syntax">                </span><span class="string-syntax">"so it doesn't represent something physical and can't be put in spatial "</span>
<span class="plain-syntax">                </span><span class="string-syntax">"relationships like this. (For the same reason that you can't put "</span>
<span class="plain-syntax">                </span><span class="string-syntax">"'southeast', the direction, inside a kitchen cupboard.)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-sm.html#SP31">&#167;31</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP31_3" class="paragraph-anchor"></a><b>&#167;31.3. </b>At last we come to it: determining the progenitor, and part-flag, for the
object under investigation.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Position this object spatially</span><span class="named-paragraph-number">31.3</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">inference</span><span class="plain-syntax"> *</span><span class="identifier-syntax">parent_setting_inference</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="3-sm.html#SP31_3_1" class="named-paragraph-link"><span class="named-paragraph">Find the inference which will decide the progenitor</span><span class="named-paragraph-number">31.3.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">parent_setting_inference</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">whereabouts</span><span class="plain-syntax"> =</span>
<span class="plain-syntax">            </span><a href="3-si.html#SP9" class="function-link"><span class="function-syntax">SpatialInferences::get_inferred_progenitor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">parent_setting_inference</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">here_flag</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="3-sm.html#SP31_3_2" class="named-paragraph-link"><span class="named-paragraph">Find the whereabouts of something here</span><span class="named-paragraph-number">31.3.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">whereabouts</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><a href="3-sm.html#SP29" class="function-link"><span class="function-syntax">Spatial::set_progenitor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">whereabouts</span><span class="plain-syntax">, </span><span class="identifier-syntax">parent_setting_inference</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">OBJECT_TREE</span><span class="plain-syntax">, </span><span class="string-syntax">"Progenitor of $O is $O\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">whereabouts</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="3-sm.html#SP31_3_3" class="named-paragraph-link"><span class="named-paragraph">Determine whether the object in question is a component part</span><span class="named-paragraph-number">31.3.3</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-sm.html#SP31">&#167;31</a> (twice).</li></ul>
<p class="commentary firstcommentary"><a id="SP31_3_1" class="paragraph-anchor"></a><b>&#167;31.3.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Find the inference which will decide the progenitor</span><span class="named-paragraph-number">31.3.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">inference</span><span class="plain-syntax"> *</span><span class="identifier-syntax">inf</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">POSITIVE_KNOWLEDGE_LOOP</span><span class="plain-syntax">(</span><span class="identifier-syntax">inf</span><span class="plain-syntax">, </span><span class="identifier-syntax">Instances::as_subject</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">), </span><span class="identifier-syntax">parentage_nowhere_inf</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="named-paragraph-container code-font"><a href="3-sm.html#SP31_3_1_1" class="named-paragraph-link"><span class="named-paragraph">Make this the determining inference</span><span class="named-paragraph-number">31.3.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">POSITIVE_KNOWLEDGE_LOOP</span><span class="plain-syntax">(</span><span class="identifier-syntax">inf</span><span class="plain-syntax">, </span><span class="identifier-syntax">Instances::as_subject</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">), </span><span class="identifier-syntax">parentage_here_inf</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="named-paragraph-container code-font"><a href="3-sm.html#SP31_3_1_1" class="named-paragraph-link"><span class="named-paragraph">Make this the determining inference</span><span class="named-paragraph-number">31.3.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">POSITIVE_KNOWLEDGE_LOOP</span><span class="plain-syntax">(</span><span class="identifier-syntax">inf</span><span class="plain-syntax">, </span><span class="identifier-syntax">Instances::as_subject</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">), </span><span class="identifier-syntax">parentage_inf</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="named-paragraph-container code-font"><a href="3-sm.html#SP31_3_1_1" class="named-paragraph-link"><span class="named-paragraph">Make this the determining inference</span><span class="named-paragraph-number">31.3.1.1</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-sm.html#SP31_3">&#167;31.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP31_3_1_1" class="paragraph-anchor"></a><b>&#167;31.3.1.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Make this the determining inference</span><span class="named-paragraph-number">31.3.1.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">parent_setting_inference</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">StandardProblems::contradiction_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_DuplicateParentage</span><span class="plain-syntax">),</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">Inferences::where_inferred</span><span class="plain-syntax">(</span><span class="identifier-syntax">parent_setting_inference</span><span class="plain-syntax">),</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">Inferences::where_inferred</span><span class="plain-syntax">(</span><span class="identifier-syntax">inf</span><span class="plain-syntax">),</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">I</span><span class="plain-syntax">,</span>
<span class="plain-syntax">            </span><span class="string-syntax">"can only be given its position once"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">            </span><span class="string-syntax">"in a single assertion sentence."</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">parent_setting_inference</span><span class="plain-syntax"> = </span><span class="identifier-syntax">inf</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-sm.html#SP31_3_1">&#167;31.3.1</a> (three times).</li></ul>
<p class="commentary firstcommentary"><a id="SP31_3_2" class="paragraph-anchor"></a><b>&#167;31.3.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Find the whereabouts of something here</span><span class="named-paragraph-number">31.3.2</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-sm.html#SP7" class="function-link"><span class="function-syntax">Spatial::object_is_a_room</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">whereabouts</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="identifier-syntax">whereabouts</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">whereabouts</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">whereabouts</span><span class="plain-syntax"> = </span><span class="identifier-syntax">implied_Stage_room</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">whereabouts</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">here_sentence</span><span class="plain-syntax"> =</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">Inferences::where_inferred</span><span class="plain-syntax">(</span><span class="identifier-syntax">parent_setting_inference</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="named-paragraph-container code-font"><a href="3-sm.html#SP31_3_2_1" class="named-paragraph-link"><span class="named-paragraph">Set the whereabouts to the last discussed room prior to this inference being drawn</span><span class="named-paragraph-number">31.3.2.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">whereabouts</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>

<span class="plain-syntax">            </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">here_sentence</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">StandardProblems::object_problem_at_sentence</span><span class="plain-syntax">(</span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_NoHere</span><span class="plain-syntax">),</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">I</span><span class="plain-syntax">,</span>
<span class="plain-syntax">                </span><span class="string-syntax">"was described as being 'here', and there doesn't seem to be any "</span>
<span class="plain-syntax">                </span><span class="string-syntax">"location being talked about at this point in the source text"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">                </span><span class="string-syntax">"so there's nowhere you can call 'here'."</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-sm.html#SP31_3">&#167;31.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP31_3_2_1" class="paragraph-anchor"></a><b>&#167;31.3.2.1. </b>This runs through the source text from the beginning up to the "here"
sentence, setting <span class="extract"><span class="extract-syntax">whereabouts</span></span> to any rooms it finds along the way, so that
when it finishes this will be set to the most recently mentioned.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Set the whereabouts to the last discussed room prior to this inference being drawn</span><span class="named-paragraph-number">31.3.2.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">SyntaxTree::traverse_up_to_ip</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">here_sentence</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><a href="3-sm.html#SP32" class="function-link"><span class="function-syntax">Spatial::seek_room</span></a><span class="plain-syntax">, (</span><span class="reserved-syntax">void</span><span class="plain-syntax"> **) &amp;</span><span class="identifier-syntax">whereabouts</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-sm.html#SP31_3_2">&#167;31.3.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP31_3_3" class="paragraph-anchor"></a><b>&#167;31.3.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Determine whether the object in question is a component part</span><span class="named-paragraph-number">31.3.3</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">inference</span><span class="plain-syntax"> *</span><span class="identifier-syntax">inf</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">POSITIVE_KNOWLEDGE_LOOP</span><span class="plain-syntax">(</span><span class="identifier-syntax">inf</span><span class="plain-syntax">, </span><span class="identifier-syntax">Instances::as_subject</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">), </span><span class="identifier-syntax">part_of_inf</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="3-sm.html#SP7" class="function-link"><span class="function-syntax">Spatial::object_is_a_room</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">)) || (</span><a href="3-tm.html#SP13" class="function-link"><span class="function-syntax">Map::instance_is_a_door</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">StandardProblems::object_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_RoomOrDoorAsPart</span><span class="plain-syntax">),</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">I</span><span class="plain-syntax">,</span>
<span class="plain-syntax">                </span><span class="string-syntax">"was set up as being part of something else, which doors and rooms "</span>
<span class="plain-syntax">                </span><span class="string-syntax">"are not allowed to be"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">                </span><span class="string-syntax">"because they are part of the fixed map of the world - if they were "</span>
<span class="plain-syntax">                </span><span class="string-syntax">"parts of something else, they might move around. (Of course, it's "</span>
<span class="plain-syntax">                </span><span class="string-syntax">"easy to make a door look as if it's part of something to the player - "</span>
<span class="plain-syntax">                </span><span class="string-syntax">"describing it as part of a wall, or bulkhead, or cottage, say - "</span>
<span class="plain-syntax">                </span><span class="string-syntax">"and if there really is an entrance that needs to move around - say, "</span>
<span class="plain-syntax">                </span><span class="string-syntax">"the hatchway on a tank - it's probably best to make it an enterable "</span>
<span class="plain-syntax">                </span><span class="string-syntax">"container.)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">part_flag</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-sm.html#SP31_3">&#167;31.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP32" class="paragraph-anchor"></a><b>&#167;32. </b></p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Spatial::seek_room</span><button class="popup" onclick="togglePopup('usagePopup22')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup22">Usage of <span class="code-font"><span class="function-syntax">Spatial::seek_room</span></span>:<br/><a href="3-sm.html#SP31_3_2_1">&#167;31.3.2.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sent</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> **</span><span class="identifier-syntax">v_I</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> **</span><span class="identifier-syntax">I</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">instance</span><span class="plain-syntax"> **) </span><span class="identifier-syntax">v_I</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">isub</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_interpretation_of_subject</span><span class="plain-syntax">(</span><span class="identifier-syntax">sent</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sub</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InstanceSubjects::to_object_instance</span><span class="plain-syntax">(</span><span class="identifier-syntax">isub</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-sm.html#SP7" class="function-link"><span class="function-syntax">Spatial::object_is_a_room</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">)) *</span><span class="identifier-syntax">I</span><span class="plain-syntax"> = </span><span class="identifier-syntax">sub</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP33" class="paragraph-anchor"></a><b>&#167;33. Completing the model, stages III and IV.</b>By the beginning of Stage III, the progenitor of every object is known, and
so is whether it is a part. It's time to start work on compiling the I6
representation of all this, but unfortunately that will need to be quite a
bit more complicated. So we're going to do this in two stages, the first
of which is to construct a pair of object trees as an intermediate state.
</p>

<p class="commentary">We have a main object tree, in fact a forest (i.e., it's probably disconnected),
to represent containment, support, carrying and wearing; and a secondary tree
for incorporation only. In this source code, we'll use the language of family
trees (parent, children, siblings) rather than horticulture (branches, leaves,
grafting). Both trees must be well-founded, and must be such that each object
is the parent of all its children. But the trees aren't independent of each
other: an object is not allowed to have a parent in both trees at once.
If it has a parent in either one, then that parent is required to be its progenitor.
</p>

<p class="commentary firstcommentary"><a id="SP34" class="paragraph-anchor"></a><b>&#167;34. </b>The following logs the more interesting tree:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Spatial::log_object_tree</span><button class="popup" onclick="togglePopup('usagePopup23')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup23">Usage of <span class="code-font"><span class="function-syntax">Spatial::log_object_tree</span></span>:<br/><a href="3-sm.html#SP38">&#167;38</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_OVER_INSTANCES</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_object</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">object_tree_parent</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><a href="3-sm.html#SP34" class="function-link"><span class="function-syntax">Spatial::log_object_tree_recursively</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>

<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Spatial::log_object_tree_recursively</span><span class="plain-syntax">(</span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">depth</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="identifier-syntax">depth</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">&gt;0) { </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"  "</span><span class="plain-syntax">); </span><span class="identifier-syntax">i</span><span class="plain-syntax">--; }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"$O\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">object_tree_child</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><a href="3-sm.html#SP34" class="function-link"><span class="function-syntax">Spatial::log_object_tree_recursively</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">object_tree_child</span><span class="plain-syntax">, </span><span class="identifier-syntax">depth</span><span class="plain-syntax">+1);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">object_tree_sibling</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><a href="3-sm.html#SP34" class="function-link"><span class="function-syntax">Spatial::log_object_tree_recursively</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">object_tree_sibling</span><span class="plain-syntax">, </span><span class="identifier-syntax">depth</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP35" class="paragraph-anchor"></a><b>&#167;35. </b>The initial state of both trees is total disconnection. They are then produced
using only two operations, which we'll call "adoption" and "parting".
</p>

<p class="commentary">The adoption routine moves X and its children to become the youngest child of Y.
The tree is grown entirely from its root by repeated use of this one operation.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Spatial::adopt_object</span><button class="popup" onclick="togglePopup('usagePopup24')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup24">Usage of <span class="code-font"><span class="function-syntax">Spatial::adopt_object</span></span>:<br/><a href="3-sm.html#SP38_2">&#167;38.2</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">orphan</span><span class="plain-syntax">, </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">foster</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">OBJECT_TREE</span><span class="plain-syntax">, </span><span class="string-syntax">"Grafting $O to be child of $O\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">orphan</span><span class="plain-syntax">, </span><span class="identifier-syntax">foster</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">orphan</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"orphan is null in adoption"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">foster</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"foster is null in adoption"</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">former_parent</span><span class="plain-syntax"> = </span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">orphan</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">object_tree_parent</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">former_parent</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="3-sm.html#SP35_1" class="named-paragraph-link"><span class="named-paragraph">Remove the object from the main object tree</span><span class="named-paragraph-number">35.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="3-sm.html#SP35_2" class="named-paragraph-link"><span class="named-paragraph">Adopt the object into the main object tree</span><span class="named-paragraph-number">35.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP36" class="paragraph-anchor"></a><b>&#167;36. </b>"Parting" is the operation of being removed from the main tree and placed
in the incorporation tree instead, but with the same parent.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Spatial::part_object</span><button class="popup" onclick="togglePopup('usagePopup25')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup25">Usage of <span class="code-font"><span class="function-syntax">Spatial::part_object</span></span>:<br/><a href="3-sm.html#SP38_2">&#167;38.2</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">orphan</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">OBJECT_TREE</span><span class="plain-syntax">, </span><span class="string-syntax">"Parting $O\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">orphan</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">orphan</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"new part is null in parting"</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">former_parent</span><span class="plain-syntax"> = </span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">orphan</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">object_tree_parent</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">former_parent</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"new part is without parent"</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="3-sm.html#SP35_1" class="named-paragraph-link"><span class="named-paragraph">Remove the object from the main object tree</span><span class="named-paragraph-number">35.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="3-sm.html#SP36_1" class="named-paragraph-link"><span class="named-paragraph">Adopt the object into the incorporation tree</span><span class="named-paragraph-number">36.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP35_1" class="paragraph-anchor"></a><b>&#167;35.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Remove the object from the main object tree</span><span class="named-paragraph-number">35.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">former_parent</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">object_tree_child</span><span class="plain-syntax"> == </span><span class="identifier-syntax">orphan</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">former_parent</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">object_tree_child</span><span class="plain-syntax"> =</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">orphan</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">object_tree_sibling</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">elder</span><span class="plain-syntax"> = </span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">former_parent</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">object_tree_child</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">elder</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">elder</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">object_tree_sibling</span><span class="plain-syntax"> == </span><span class="identifier-syntax">orphan</span><span class="plain-syntax">)</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">elder</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">object_tree_sibling</span><span class="plain-syntax"> =</span>
<span class="plain-syntax">                    </span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">orphan</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">object_tree_sibling</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">elder</span><span class="plain-syntax"> = </span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">elder</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">object_tree_sibling</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">orphan</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">object_tree_parent</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">orphan</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">object_tree_sibling</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-sm.html#SP35">&#167;35</a> and <a href="3-sm.html#SP36">&#167;36</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP35_2" class="paragraph-anchor"></a><b>&#167;35.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Adopt the object into the main object tree</span><span class="named-paragraph-number">35.2</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">foster</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">object_tree_child</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">foster</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">object_tree_child</span><span class="plain-syntax"> = </span><span class="identifier-syntax">orphan</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">elder</span><span class="plain-syntax"> = </span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">foster</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">object_tree_child</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">elder</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">object_tree_sibling</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">elder</span><span class="plain-syntax"> = </span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">elder</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">object_tree_sibling</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">elder</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">object_tree_sibling</span><span class="plain-syntax"> = </span><span class="identifier-syntax">orphan</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">orphan</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">object_tree_parent</span><span class="plain-syntax"> = </span><span class="identifier-syntax">foster</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-sm.html#SP35">&#167;35</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP36_1" class="paragraph-anchor"></a><b>&#167;36.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Adopt the object into the incorporation tree</span><span class="named-paragraph-number">36.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">former_parent</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">incorp_tree_child</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">former_parent</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">incorp_tree_child</span><span class="plain-syntax"> = </span><span class="identifier-syntax">orphan</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">existing_part</span><span class="plain-syntax"> = </span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">former_parent</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">incorp_tree_child</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">existing_part</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">incorp_tree_sibling</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">existing_part</span><span class="plain-syntax"> = </span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">existing_part</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">incorp_tree_sibling</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">existing_part</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">incorp_tree_sibling</span><span class="plain-syntax"> = </span><span class="identifier-syntax">orphan</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">orphan</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">incorp_tree_parent</span><span class="plain-syntax"> = </span><span class="identifier-syntax">former_parent</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-sm.html#SP36">&#167;36</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP37" class="paragraph-anchor"></a><b>&#167;37. </b>What will we use the trees for? Well, one use is to tell other features
which depend on Spatial whether or not one object spatially contains another:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Spatial::encloses</span><button class="popup" onclick="togglePopup('usagePopup26')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup26">Usage of <span class="code-font"><span class="function-syntax">Spatial::encloses</span></span>:<br/>Regions - <a href="3-rgn.html#SP8">&#167;8</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I1</span><span class="plain-syntax">, </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">I1</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">I1</span><span class="plain-syntax"> = </span><a href="3-sm.html#SP29" class="function-link"><span class="function-syntax">Spatial::progenitor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I1</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">I1</span><span class="plain-syntax"> == </span><span class="identifier-syntax">I2</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP38" class="paragraph-anchor"></a><b>&#167;38. </b>But the main use for the trees is, as noted above, to form a convenient
intermediate state between the mass of progenitor data and the messy Inter
code it turns into. Here goes:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Spatial::spatial_stage_III</span><button class="popup" onclick="togglePopup('usagePopup27')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup27">Usage of <span class="code-font"><span class="function-syntax">Spatial::spatial_stage_III</span></span>:<br/><a href="3-sm.html#SP26">&#167;26</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">well_founded</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="3-sm.html#SP38_1" class="named-paragraph-link"><span class="named-paragraph">Check the well-foundedness of the hierarchy of the set of progenitors</span><span class="named-paragraph-number">38.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">well_founded</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="3-sm.html#SP38_2" class="named-paragraph-link"><span class="named-paragraph">Expand the progenitor data into the two object trees</span><span class="named-paragraph-number">38.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="3-sm.html#SP38_3" class="named-paragraph-link"><span class="named-paragraph">Assert the portability of any item carried or supported by a person</span><span class="named-paragraph-number">38.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="3-sm.html#SP38_4" class="named-paragraph-link"><span class="named-paragraph">Assert Inter-level properties to express the spatial structure</span><span class="named-paragraph-number">38.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="3-sm.html#SP38_5" class="named-paragraph-link"><span class="named-paragraph">Set up the compilation sequence so that it traverses the main object tree</span><span class="named-paragraph-number">38.5</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Log::aspect_switched_on</span><span class="plain-syntax">(</span><span class="constant-syntax">OBJECT_TREE_DA</span><span class="plain-syntax">)) </span><a href="3-sm.html#SP34" class="function-link"><span class="function-syntax">Spatial::log_object_tree</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP38_1" class="paragraph-anchor"></a><b>&#167;38.1. </b>The following verifies, in a brute-force way, that there are no cycles in
the directed graph formed by the objects and progeniture. (We're doing this
now, rather than at Stage II above, because other features may also have
changed progenitors at Stage II.)
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Check the well-foundedness of the hierarchy of the set of progenitors</span><span class="named-paragraph-number">38.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">max_loop</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NUMBER_CREATED</span><span class="plain-syntax">(</span><span class="identifier-syntax">instance</span><span class="plain-syntax">) + </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_OVER_INSTANCES</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_object</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">k</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I2</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">I2</span><span class="plain-syntax"> = </span><a href="3-sm.html#SP29" class="function-link"><span class="function-syntax">Spatial::progenitor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">), </span><span class="identifier-syntax">k</span><span class="plain-syntax">=0; (</span><span class="identifier-syntax">I2</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">k</span><span class="plain-syntax">&lt;</span><span class="identifier-syntax">max_loop</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">I2</span><span class="plain-syntax"> = </span><a href="3-sm.html#SP29" class="function-link"><span class="function-syntax">Spatial::progenitor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I2</span><span class="plain-syntax">), </span><span class="identifier-syntax">k</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">I2</span><span class="plain-syntax"> == </span><span class="identifier-syntax">I</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">                </span><span class="named-paragraph-container code-font"><a href="3-sm.html#SP38_1_1" class="named-paragraph-link"><span class="named-paragraph">Diagnose the ill-foundedness with a problem message</span><span class="named-paragraph-number">38.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><a href="3-sm.html#SP30" class="function-link"><span class="function-syntax">Spatial::void_progenitor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">); </span><span class="comment-syntax"> thus cutting the cycle</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">well_founded</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            }</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-sm.html#SP38">&#167;38</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP38_1_1" class="paragraph-anchor"></a><b>&#167;38.1.1. </b>The cutest of all the object problem messages, really:
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Diagnose the ill-foundedness with a problem message</span><span class="named-paragraph-number">38.1.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">Problems::quote_object</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">I</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">StandardProblems::handmade_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_IllFounded</span><span class="plain-syntax">));</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span><span class="string-syntax">"The %1 seems to be containing itself: "</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I3</span><span class="plain-syntax"> = </span><span class="identifier-syntax">I</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">IW</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Instances::get_name</span><span class="plain-syntax">(</span><span class="identifier-syntax">I3</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">creator</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Diagrams::new_UNPARSED_NOUN</span><span class="plain-syntax">(</span><span class="identifier-syntax">IW</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Problems::quote_object</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">I3</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Problems::quote_source</span><span class="plain-syntax">(3, </span><span class="identifier-syntax">creator</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span><span class="string-syntax">"%2 (created by %3) "</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">I3</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">part_flag</span><span class="plain-syntax">) </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span><span class="string-syntax">"part of "</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span><span class="string-syntax">"in "</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">I3</span><span class="plain-syntax"> = </span><a href="3-sm.html#SP29" class="function-link"><span class="function-syntax">Spatial::progenitor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I3</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">I3</span><span class="plain-syntax"> == </span><span class="identifier-syntax">I</span><span class="plain-syntax">) </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span><span class="string-syntax">"%1... and so on. This is forbidden."</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-sm.html#SP38_1">&#167;38.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP38_2" class="paragraph-anchor"></a><b>&#167;38.2. </b>Intermediate states are always suspect in program design, and we might
ask what's wrong with simply making the trees as we go along, rather than
storing all of those progenitors and then converting them into the trees.
We don't do that because (for reasons to do with "here" and with how work
is shared among the features) the progenitors are determined in an undefined
order; if we made the object tree as we went along, the spatial model would
be perfectly correct, but siblings &mdash; say, the three things on the grass in
the Croquet Lawn &mdash; would be compiled in the Inter code in some undefined
order. This order matters because it affects the text produced by typical
room descriptions: "You can also see a box, a ball and a peg here." might
become "You can also see a ball, a box and a peg here."
</p>

<p class="commentary">Inform therefore needs a definite rule of ordering, and this rule is that
siblings appear in their order of creation in the I7 source text, with the
first created being the eldest child. Looping over the objects to add them
to the trees in creation order achieves this nicely:
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Expand the progenitor data into the two object trees</span><span class="named-paragraph-number">38.2</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_OVER_INSTANCES</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_object</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-sm.html#SP29" class="function-link"><span class="function-syntax">Spatial::progenitor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">))</span>
<span class="plain-syntax">            </span><a href="3-sm.html#SP35" class="function-link"><span class="function-syntax">Spatial::adopt_object</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><a href="3-sm.html#SP29" class="function-link"><span class="function-syntax">Spatial::progenitor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">));</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">part_flag</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><a href="3-sm.html#SP36" class="function-link"><span class="function-syntax">Spatial::part_object</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-sm.html#SP38">&#167;38</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP38_3" class="paragraph-anchor"></a><b>&#167;38.3. </b>As a brief aside: if something is carried by a living person, we can
reasonably assume it's portable. (This is needed in particular to ensure that
supporters which are initially carried don't pick up "fixed in place" in
the absence of other information.)
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Assert the portability of any item carried or supported by a person</span><span class="named-paragraph-number">38.3</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_OVER_INSTANCES</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_object</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">portable</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">J</span><span class="plain-syntax"> = </span><span class="identifier-syntax">I</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">part_flag</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">J</span><span class="plain-syntax"> = </span><a href="3-sm.html#SP29" class="function-link"><span class="function-syntax">Spatial::progenitor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">); </span><span class="identifier-syntax">J</span><span class="plain-syntax">; </span><span class="identifier-syntax">J</span><span class="plain-syntax"> = </span><a href="3-sm.html#SP29" class="function-link"><span class="function-syntax">Spatial::progenitor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">J</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">J</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">part_flag</span><span class="plain-syntax">) </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Instances::of_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">J</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_person</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">                    </span><span class="identifier-syntax">portable</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                    </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                }</span>
<span class="plain-syntax">            }</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">portable</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">progenitor_set_at</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">EitherOrProperties::assert</span><span class="plain-syntax">(</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">P_fixed_in_place</span><span class="plain-syntax">, </span><span class="identifier-syntax">Instances::as_subject</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">), </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">CERTAIN_CE</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-sm.html#SP38">&#167;38</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP38_4" class="paragraph-anchor"></a><b>&#167;38.4. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Assert Inter-level properties to express the spatial structure</span><span class="named-paragraph-number">38.4</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="3-sm.html#SP38_4_1" class="named-paragraph-link"><span class="named-paragraph">Assert an explicit default description value for the room kind</span><span class="named-paragraph-number">38.4.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="3-sm.html#SP38_4_2" class="named-paragraph-link"><span class="named-paragraph">Assert room and thing indicator properties</span><span class="named-paragraph-number">38.4.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="3-sm.html#SP38_4_3" class="named-paragraph-link"><span class="named-paragraph">Assert container and supporter indicator properties</span><span class="named-paragraph-number">38.4.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="3-sm.html#SP38_4_4" class="named-paragraph-link"><span class="named-paragraph">Assert incorporation tree properties</span><span class="named-paragraph-number">38.4.4</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-sm.html#SP38">&#167;38</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP38_4_1" class="paragraph-anchor"></a><b>&#167;38.4.1. </b>We need to make sure that every room does have an Inter <span class="extract"><span class="extract-syntax">description</span></span> value
which can be written to (i.e., we need to avoid accidental use of the Z-machine's
readable-only default properties feature); hence the following, which ensures
that any room with no explicit description will inherit <span class="extract"><span class="extract-syntax">EMPTY_TEXT_VALUE</span></span>
as a value for <span class="extract"><span class="extract-syntax">description</span></span> from the room class.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Assert an explicit default description value for the room kind</span><span class="named-paragraph-number">38.4.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">K_room</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">inference</span><span class="plain-syntax"> *</span><span class="identifier-syntax">inf</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">desc_seen</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">POSITIVE_KNOWLEDGE_LOOP</span><span class="plain-syntax">(</span><span class="identifier-syntax">inf</span><span class="plain-syntax">, </span><span class="identifier-syntax">KindSubjects::from_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_room</span><span class="plain-syntax">), </span><span class="identifier-syntax">property_inf</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">PropertyInferences::get_property</span><span class="plain-syntax">(</span><span class="identifier-syntax">inf</span><span class="plain-syntax">) == </span><span class="identifier-syntax">P_description</span><span class="plain-syntax">)</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">desc_seen</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">desc_seen</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">val</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">val</span><span class="plain-syntax">, </span><span class="string-syntax">"\"\""</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">ValueProperties::assert</span><span class="plain-syntax">(</span><span class="identifier-syntax">P_description</span><span class="plain-syntax">, </span><span class="identifier-syntax">KindSubjects::from_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_room</span><span class="plain-syntax">),</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">Rvalues::from_unescaped_wording</span><span class="plain-syntax">(</span><span class="identifier-syntax">Feeds::feed_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">val</span><span class="plain-syntax">)), </span><span class="identifier-syntax">LIKELY_CE</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">val</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-sm.html#SP38_4">&#167;38.4</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP38_4_2" class="paragraph-anchor"></a><b>&#167;38.4.2. </b>These Inter-only properties exist for speed. They're implemented in Inter as
attributes, which means that testing them is very fast and there is no memory
overhead for their storage. That shaves a little time off route-finding in
extensive maps.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Assert room and thing indicator properties</span><span class="named-paragraph-number">38.4.2</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">P_mark_as_room</span><span class="plain-syntax"> = </span><span class="identifier-syntax">EitherOrProperties::new_nameless</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"mark_as_room"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">P_mark_as_thing</span><span class="plain-syntax"> = </span><span class="identifier-syntax">EitherOrProperties::new_nameless</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"mark_as_thing"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_OVER_INSTANCES</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_object</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Instances::of_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_room</span><span class="plain-syntax">))</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">EitherOrProperties::assert</span><span class="plain-syntax">(</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">P_mark_as_room</span><span class="plain-syntax">, </span><span class="identifier-syntax">Instances::as_subject</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">), </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">, </span><span class="identifier-syntax">CERTAIN_CE</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Instances::of_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_thing</span><span class="plain-syntax">))</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">EitherOrProperties::assert</span><span class="plain-syntax">(</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">P_mark_as_thing</span><span class="plain-syntax">, </span><span class="identifier-syntax">Instances::as_subject</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">), </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">, </span><span class="identifier-syntax">CERTAIN_CE</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-sm.html#SP38_4">&#167;38.4</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP38_4_3" class="paragraph-anchor"></a><b>&#167;38.4.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Assert container and supporter indicator properties</span><span class="named-paragraph-number">38.4.3</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">P_container</span><span class="plain-syntax"> = </span><span class="identifier-syntax">EitherOrProperties::new_nameless</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"container"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">P_supporter</span><span class="plain-syntax"> = </span><span class="identifier-syntax">EitherOrProperties::new_nameless</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"supporter"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_OVER_INSTANCES</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_object</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Instances::of_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_container</span><span class="plain-syntax">))</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">EitherOrProperties::assert</span><span class="plain-syntax">(</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">P_container</span><span class="plain-syntax">, </span><span class="identifier-syntax">Instances::as_subject</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">), </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">, </span><span class="identifier-syntax">CERTAIN_CE</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Instances::of_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_supporter</span><span class="plain-syntax">))</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">EitherOrProperties::assert</span><span class="plain-syntax">(</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">P_supporter</span><span class="plain-syntax">, </span><span class="identifier-syntax">Instances::as_subject</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">), </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">, </span><span class="identifier-syntax">CERTAIN_CE</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-sm.html#SP38_4">&#167;38.4</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP38_4_4" class="paragraph-anchor"></a><b>&#167;38.4.4. </b>The main spatial tree is expressed in the compiled Inter code in an implicit
way, using the Inter object tree, but the incorporation tree is expressed using
a triplet of Inter-only properties:
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Assert incorporation tree properties</span><span class="named-paragraph-number">38.4.4</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">P_component_parent</span><span class="plain-syntax"> =</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">ValueProperties::new_nameless</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"component_parent"</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_object</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">P_component_child</span><span class="plain-syntax"> =</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">ValueProperties::new_nameless</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"component_child"</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_object</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">P_component_sibling</span><span class="plain-syntax"> =</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">ValueProperties::new_nameless</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"component_sibling"</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_object</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">K_thing</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nothing_constant</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Rvalues::new_nothing_object_constant</span><span class="plain-syntax">();</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">ValueProperties::assert</span><span class="plain-syntax">(</span><span class="identifier-syntax">P_component_parent</span><span class="plain-syntax">, </span><span class="identifier-syntax">KindSubjects::from_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_thing</span><span class="plain-syntax">),</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">nothing_constant</span><span class="plain-syntax">, </span><span class="identifier-syntax">CERTAIN_CE</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">ValueProperties::assert</span><span class="plain-syntax">(</span><span class="identifier-syntax">P_component_child</span><span class="plain-syntax">, </span><span class="identifier-syntax">KindSubjects::from_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_thing</span><span class="plain-syntax">),</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">nothing_constant</span><span class="plain-syntax">, </span><span class="identifier-syntax">CERTAIN_CE</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">ValueProperties::assert</span><span class="plain-syntax">(</span><span class="identifier-syntax">P_component_sibling</span><span class="plain-syntax">, </span><span class="identifier-syntax">KindSubjects::from_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_thing</span><span class="plain-syntax">),</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">nothing_constant</span><span class="plain-syntax">, </span><span class="identifier-syntax">CERTAIN_CE</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_OVER_INSTANCES</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_object</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">incorp_tree_parent</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cp</span><span class="plain-syntax">) </span><span class="identifier-syntax">ValueProperties::assert</span><span class="plain-syntax">(</span><span class="identifier-syntax">P_component_parent</span><span class="plain-syntax">, </span><span class="identifier-syntax">Instances::as_subject</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">),</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">Rvalues::from_instance</span><span class="plain-syntax">(</span><span class="identifier-syntax">cp</span><span class="plain-syntax">), </span><span class="identifier-syntax">CERTAIN_CE</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">incorp_tree_child</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cc</span><span class="plain-syntax">) </span><span class="identifier-syntax">ValueProperties::assert</span><span class="plain-syntax">(</span><span class="identifier-syntax">P_component_child</span><span class="plain-syntax">, </span><span class="identifier-syntax">Instances::as_subject</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">),</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">Rvalues::from_instance</span><span class="plain-syntax">(</span><span class="identifier-syntax">cc</span><span class="plain-syntax">), </span><span class="identifier-syntax">CERTAIN_CE</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cs</span><span class="plain-syntax"> = </span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">incorp_tree_sibling</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cs</span><span class="plain-syntax">) </span><span class="identifier-syntax">ValueProperties::assert</span><span class="plain-syntax">(</span><span class="identifier-syntax">P_component_sibling</span><span class="plain-syntax">, </span><span class="identifier-syntax">Instances::as_subject</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">),</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">Rvalues::from_instance</span><span class="plain-syntax">(</span><span class="identifier-syntax">cs</span><span class="plain-syntax">), </span><span class="identifier-syntax">CERTAIN_CE</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-sm.html#SP38_4">&#167;38.4</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP38_5" class="paragraph-anchor"></a><b>&#167;38.5. </b>Because Inform 6 requires objects to be defined in a traversal order for
the main spatial tree (only the main one because Inter has no concept of
incorporation), we use the main tree to determine the compilation sequence
for objects:
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Set up the compilation sequence so that it traverses the main object tree</span><span class="named-paragraph-number">38.5</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">OrderingInstances::begin</span><span class="plain-syntax">();</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_OVER_INSTANCES</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_object</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">object_tree_parent</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><a href="3-sm.html#SP39" class="function-link"><span class="function-syntax">Spatial::add_to_object_sequence</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-sm.html#SP38">&#167;38</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP39" class="paragraph-anchor"></a><b>&#167;39. </b></p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Spatial::add_to_object_sequence</span><button class="popup" onclick="togglePopup('usagePopup28')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup28">Usage of <span class="code-font"><span class="function-syntax">Spatial::add_to_object_sequence</span></span>:<br/><a href="3-sm.html#SP38_5">&#167;38.5</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">depth</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">OrderingInstances::place_next</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">definition_depth</span><span class="plain-syntax"> = </span><span class="identifier-syntax">depth</span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">object_tree_child</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><a href="3-sm.html#SP39" class="function-link"><span class="function-syntax">Spatial::add_to_object_sequence</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">object_tree_child</span><span class="plain-syntax">, </span><span class="identifier-syntax">depth</span><span class="plain-syntax">+1);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">object_tree_sibling</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><a href="3-sm.html#SP39" class="function-link"><span class="function-syntax">Spatial::add_to_object_sequence</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">object_tree_sibling</span><span class="plain-syntax">, </span><span class="identifier-syntax">depth</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP40" class="paragraph-anchor"></a><b>&#167;40. </b>The "definition depth" is the same thing as the depth in the main tree;
0 for a room, 1 for a player standing in that room, 2 for his hat, and so on.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Spatial::get_definition_depth</span><span class="plain-syntax">(</span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">FEATURE_ACTIVE</span><span class="plain-syntax">(</span><span class="identifier-syntax">spatial</span><span class="plain-syntax">))</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">SPATIAL_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">definition_depth</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP41" class="paragraph-anchor"></a><b>&#167;41. </b>By Stage IV we're nearly all done, except for a little checking of the
degenerate case where Inform is just binding up an existing story file, so
that there's really no spatial model at all &mdash; the world is, or should be,
empty.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Spatial::spatial_stage_IV</span><button class="popup" onclick="togglePopup('usagePopup29')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup29">Usage of <span class="code-font"><span class="function-syntax">Spatial::spatial_stage_IV</span></span>:<br/><a href="3-sm.html#SP26">&#167;26</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Task::wraps_existing_storyfile</span><span class="plain-syntax">()) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">implied_Stage_room</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">LOOP_OVER_INSTANCES</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_object</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-sm.html#SP7" class="function-link"><span class="function-syntax">Spatial::object_is_a_room</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">StandardProblems::unlocated_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(),</span>
<span class="plain-syntax">                    </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_RoomInIgnoredSource</span><span class="plain-syntax">),</span>
<span class="plain-syntax">                    </span><span class="string-syntax">"This is supposed to be a source text which only contains "</span>
<span class="plain-syntax">                    </span><span class="string-syntax">"release instructions to bind up an existing story file "</span>
<span class="plain-syntax">                    </span><span class="string-syntax">"(for instance, one produced using Inform 6). That's because "</span>
<span class="plain-syntax">                    </span><span class="string-syntax">"the instruction 'Release along with an existing story file' "</span>
<span class="plain-syntax">                    </span><span class="string-syntax">"is present. So the source text must not contain rooms or "</span>
<span class="plain-syntax">                    </span><span class="string-syntax">"other game design - these would be ignored."</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            }</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP42" class="paragraph-anchor"></a><b>&#167;42. </b>At last Stage V, where the only remaining task is to set the benchmark room.
It's where the player begins, or if the player begins out of play for some
reason, it's the first-created room. (The benchmark is used only in indexing.)
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">benchmark_room</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Spatial::spatial_stage_V</span><button class="popup" onclick="togglePopup('usagePopup30')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup30">Usage of <span class="code-font"><span class="function-syntax">Spatial::spatial_stage_V</span></span>:<br/><a href="3-sm.html#SP26">&#167;26</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">benchmark_room</span><span class="plain-syntax"> = </span><a href="3-tp.html#SP7" class="function-link"><span class="function-syntax">Player::get_start_room</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">benchmark_room</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">LOOP_OVER_INSTANCES</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_room</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">benchmark_room</span><span class="plain-syntax"> = </span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>

<span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="function-syntax">Spatial::get_benchmark_room</span><button class="popup" onclick="togglePopup('usagePopup31')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup31">Usage of <span class="code-font"><span class="function-syntax">Spatial::get_benchmark_room</span></span>:<br/>Mapping Hint Requests - <a href="3-mhr.html#SP11_4_1">&#167;11.4.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">benchmark_room</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<nav role="progress"><div class="progresscontainer">
    <ul class="progressbar"><li class="progressprev"><a href="2-tbf.html">&#10094;</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-im.html">1</a></li><li class="progresschapter"><a href="2-bd.html">2</a></li><li class="progresscurrentchapter">3</li><li class="progresscurrent">sm</li><li class="progresssection"><a href="3-enah.html">enah</a></li><li class="progresssection"><a href="3-sr.html">sr</a></li><li class="progresssection"><a href="3-si.html">si</a></li><li class="progresssection"><a href="3-prs.html">prs</a></li><li class="progresssection"><a href="3-tp.html">tp</a></li><li class="progresssection"><a href="3-dvc.html">dvc</a></li><li class="progresssection"><a href="3-bck.html">bck</a></li><li class="progresssection"><a href="3-rgn.html">rgn</a></li><li class="progresssection"><a href="3-tm.html">tm</a></li><li class="progresssection"><a href="3-mcr.html">mcr</a></li><li class="progresssection"><a href="3-tr.html">tr</a></li><li class="progresssection"><a href="3-scn.html">scn</a></li><li class="progresssection"><a href="3-ts.html">ts</a></li><li class="progresssection"><a href="3-mhr.html">mhr</a></li><li class="progresschapter"><a href="4-ap.html">4</a></li><li class="progresschapter"><a href="5-pp.html">5</a></li><li class="progresschapter"><a href="6-dlg.html">6</a></li><li class="progressnext"><a href="3-enah.html">&#10095;</a></li></ul></div>
</nav><!-- End of weave -->

		</main>
	</body>
</html>

